Skip to content

feat(feature-ideation): add curated reputable source list for Mary#102

Merged
don-petry merged 17 commits into
mainfrom
feat/feature-ideation-sources-list
Apr 17, 2026
Merged

feat(feature-ideation): add curated reputable source list for Mary#102
don-petry merged 17 commits into
mainfrom
feat/feature-ideation-sources-list

Conversation

@don-petry

@don-petry don-petry commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds standards/feature-ideation-sources.md — an org-curated, PR-reviewed list of reputable web pages, RSS/Atom feeds, podcasts, and YouTube channels that the BMAD Analyst (Mary) consults during Phase 2: Market Research of the feature-ideation pipeline. Sources are organised into 9 categories (AI/ML labs, AI research, dev tooling/changelogs, security, eng practice/industry analysis, newsletters, podcasts, YouTube, conferences) with a one-line justification for every entry.
  • Wires the list into .github/workflows/feature-ideation-reusable.yml: a new actions/checkout step pulls petry-projects/.github@v1 into .petry-standards/ on the runner (public repo, default GITHUB_TOKEN is sufficient), and the Phase 2 prompt is updated to instruct Mary to read the source list first, prefer listed RSS feeds over open web search, and only fall back to open search for uncovered threads. Phase 8's step-summary template gains an optional "Suggested Additions to Reputable Source List" section so high-value sources that keep recurring during runs surface for human review.
  • Documents the new file in standards/ci-standards.md §8 as the third component of the feature-ideation system, alongside the reusable workflow and the caller stub.

Why

Without a curated seed list, Mary's Phase 2 research starts cold every week and re-discovers the same primary sources via open search — wasting turns on Opus 4.6 (~$2-3/run today) and occasionally citing weaker secondary sources when SEO results crowd out the primary ones. A versioned, PR-reviewed list:

  • Gives the org a single place to add/remove trusted sources. Changes propagate to every BMAD adopter on the next scheduled run, matching how standards/workflows/* and ci-standards.md already work.
  • Lets Mary prefer structured RSS/Atom feeds (where listed) over HTML scraping, which is both cheaper and more reliable as a "what's new since last scan" signal.
  • Captures org judgement about what counts as "reputable" — a judgement we don't want re-derived from scratch every Friday morning.

The list is explicitly a floor, not a ceiling: Mary still follows threads to other reputable sources when warranted, and the new step-summary section gives a feedback loop for adding them via PR.

Test plan

  • Manually trigger feature-ideation.yml on a BMAD adopter (TalkTerm) via workflow_dispatch and confirm the run logs show the new "Checkout central standards" step succeeding.
  • Confirm the analyst job's tool-use log shows a Read of .petry-standards/standards/feature-ideation-sources.md early in Phase 2.
  • Confirm at least one Discussion proposal cites a source that appears in the list (or check the step summary for a "Suggested Additions" entry if it relied on a non-listed source).
  • Verify no regression in Discussion creation/update behaviour vs. the previous run.
  • Sanity-check gh repo view petry-projects/.github is still public — if it ever flips to private, the checkout step will need a PAT.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Repo-local reputable sources list as primary seed for market research (optional path override) and a new manual self-test workflow for feature ideation.
    • Added a “last successful run” checkpoint to limit research to newer feed/changelog items; signals schema version bumped accordingly.
  • Chores

    • Expanded workflow runtime permissions to enable required read access.
  • Documentation

    • Added comprehensive reputable-sources template and updated adoption guidance.
  • Tests

    • Updated fixtures and tests to cover the new checkpoint and schema.

Copilot AI review requested due to automatic review settings April 9, 2026 00:55
@coderabbitai

coderabbitai Bot commented Apr 9, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@don-petry has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 34 minutes and 9 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 34 minutes and 9 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: b7899b96-e677-4e17-a79a-7093bf87068b

📥 Commits

Reviewing files that changed from the base of the PR and between f3dfa6b and 8ffa692.

📒 Files selected for processing (2)
  • .github/workflows/feature-ideation-reusable.yml
  • .github/workflows/feature-ideation.yml
📝 Walkthrough

Walkthrough

Adds a repo-local configurable reputable source list input, a last_successful_run feed checkpoint propagated through schema, scripts, and tests, and updates Phase 2 prompt and workflow permissions to prefer that sources file and constrain research to items newer than the checkpoint.

Changes

Cohort / File(s) Summary
Reusable workflow
/.github/workflows/feature-ideation-reusable.yml
Add sources_file reusable-workflow input (default .github/feature-ideation-sources.md), expand gather-signals job permissions to include actions: read, and update Phase 2 prompt to seed WebFetch/WebSearch from the repo-local sources file and apply a last_successful_run cutoff.
Repository workflow caller / self-test
standards/workflows/feature-ideation.yml, /.github/workflows/feature-ideation.yml
Caller stubs: pin reusable workflow uses: to a commit SHA, add commented sources_file guidance, forward sources_file to reusable workflow, and adjust job permissions (add actions: read). Add a dry-run self-test workflow that references the standards sources file.
Standards docs & template
standards/ci-standards.md, standards/feature-ideation-sources.md
Add "Reputable Source List" guidance to CI standards, explain repo-local sources-file propagation and adoption steps, and add a starter curated sources template with curation rules and categorized feed recommendations.
Signals schema
/.github/schemas/signals.schema.json
Bump schema comment version to 1.1.0 and add required top-level last_successful_run (string, date-time) to properties and required.
Collection scripts
/.github/scripts/feature-ideation/collect-signals.sh
Bump SCHEMA_VERSION to 1.1.0; call gh run list to determine last_successful_run (fallback to 30 days ago), validate timestamp, pass checkpoint into compose_signals, and include .last_successful_run in the step summary.
Compose helper
/.github/scripts/feature-ideation/lib/compose-signals.sh
compose_signals() now expects 12 positional args (added last_successful_run at position 10), include it in composed JSON and validation; adjusted argument parsing and usage message.
Tests & fixtures
test/workflows/feature-ideation/*.bats, test/.../fixtures/*, test/.../gh-responses/run-list-last-success.txt
Update Bats stubs to include initial gh run list call and fixture line; pass new timestamp arg into compose_signals tests; update expected .signals.json fixtures to schema 1.1.0 and include last_successful_run.

Sequence Diagram(s)

sequenceDiagram
    actor Runner as GitHub Actions Runner
    participant Caller as Repo workflow caller
    participant Reusable as Reusable workflow
    participant GH as gh CLI
    participant Script as collect-signals.sh
    participant Composer as compose-signals.sh
    participant Sources as Repo-local sources file
    participant Output as signals.json / Step Summary

    Runner->>Caller: trigger workflow
    Caller->>Reusable: invoke reusable workflow (with sources_file)
    Reusable->>GH: gh run list --workflow=feature-ideation.yml --status=success --limit=1
    GH-->>Script: return last successful run timestamp
    Reusable->>Sources: read configured `sources_file` (if present)
    Script->>Composer: call compose_signals(..., last_successful_run, ...)
    Reusable->>Reusable: Phase 2 prompt seeds searches from sources_file and filters items > last_successful_run
    Composer-->>Output: emit `signals.json` (includes last_successful_run)
    Reusable-->>Output: print step summary including checkpoint and omissions
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(feature-ideation): add curated reputable source list for Mary' accurately describes the primary change—adding a new standards/feature-ideation-sources.md file and integrating it into the feature-ideation workflow to provide Mary with a curated list of reputable sources for Phase 2 market research.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/feature-ideation-sources-list

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds an org-curated “reputable sources” list for the Feature Ideation (BMAD Analyst “Mary”) pipeline and wires it into the reusable workflow so Phase 2 market research starts from a consistent set of trusted primary sources.

Changes:

  • Introduces standards/feature-ideation-sources.md with categorized sources (sites/feeds/podcasts/YouTube/conferences) and per-entry justification.
  • Updates .github/workflows/feature-ideation-reusable.yml to checkout central standards into .petry-standards/ and adjust the Phase 2 prompt + step-summary template accordingly.
  • Documents the new source-list component in standards/ci-standards.md (Feature Ideation section).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
standards/feature-ideation-sources.md New curated list Mary is instructed to read first during Phase 2 market research.
standards/ci-standards.md Documents the source list as a formal component of the Feature Ideation system.
.github/workflows/feature-ideation-reusable.yml Checks out central standards and updates the Phase 2 prompt + step summary to incorporate the list.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread standards/feature-ideation-sources.md Outdated
Comment thread standards/feature-ideation-sources.md Outdated
Comment thread .github/workflows/feature-ideation-reusable.yml Outdated
Comment thread standards/ci-standards.md Outdated
coderabbitai[bot]
coderabbitai Bot previously requested changes Apr 9, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/feature-ideation-reusable.yml:
- Around line 223-229: The checkout step named "Checkout central standards
(reputable source list)" must not hard-fail the job; change the actions/checkout
step (uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd) to be
non-blocking by adding continue-on-error: true to that step and emit a clear
warning if it failed (e.g., a follow-up run: echo "Central standards checkout
failed, proceeding with fallback" when the step result is failure) so the
workflow can continue to the documented fallback (open web search).

In `@standards/feature-ideation-sources.md`:
- Around line 60-62: The RSS feed URLs for the arXiv entries "arXiv cs.AI",
"arXiv cs.CL", and "arXiv cs.LG" use http and must be updated to use HTTPS to
ensure transport integrity; locate the three table rows containing the
export.arxiv.org/rss links and replace the "http://" prefix with "https://" for
each feed URL so the automated evidence-gathering uses encrypted feeds.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5d67ce26-20b5-4f93-9d7e-41860be725e0

📥 Commits

Reviewing files that changed from the base of the PR and between 497c2b7 and 2732d4b.

📒 Files selected for processing (3)
  • .github/workflows/feature-ideation-reusable.yml
  • standards/ci-standards.md
  • standards/feature-ideation-sources.md

Comment thread .github/workflows/feature-ideation-reusable.yml Outdated
Comment thread standards/feature-ideation-sources.md Outdated
@don-petry

Copy link
Copy Markdown
Contributor Author

Review — fix requested (cycle 1/3)

The automated review identified the following issues. Please address each one:

Findings to fix

  • [major] .github/workflows/feature-ideation-reusable.yml:223 — The Checkout central standards step does not set continue-on-error: true. If petry-projects/.github is unavailable or the v1 tag is deleted, the entire workflow job will fail. The Phase 2 prompt already documents a fallback ('If the list itself is missing or empty, log a warning and proceed with open web search'), but that fallback is unreachable if the runner halts before Claude is invoked. Fix: add continue-on-error: true to the step and emit a warning step (e.g. if: steps.<id>.outcome == 'failure') so the AI can proceed gracefully.
  • [minor] standards/feature-ideation-sources.md:60 — Three arXiv RSS feed URLs use http:// instead of https://: http://export.arxiv.org/rss/cs.AI, http://export.arxiv.org/rss/cs.CL, http://export.arxiv.org/rss/cs.LG. While these are read as reference data rather than executed, using plaintext HTTP degrades transport integrity. Update all three to https://.
  • [minor] .github/workflows/feature-ideation-reusable.yml:229 — The secondary checkout uses a mutable tag reference (ref: v1) for petry-projects/.github rather than a pinned commit SHA. If the v1 tag is moved to a different commit (accidentally or maliciously), the runner will check out different content without any diff visibility. The impact is limited since the content is markdown consumed as AI context (not executed), but pinning to a SHA is consistent with how other Actions are pinned in this workflow.

Additional tasks

  1. Resolve all unresolved review thread comments from other reviewers
  2. Ensure all CI checks pass after your changes
  3. Rebase on main if the branch is behind
  4. Do NOT modify files unrelated to the findings above

The review cascade will automatically re-review after new commits are pushed.

@don-petry don-petry left a comment

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.

Automated review — NEEDS HUMAN REVIEW

Risk: MEDIUM
Reviewed commit: 4147369e9fa8ca4c5dafdeed9b74eb41d961dc82
Cascade: triage → deep (see triage: haiku 4.5 → deep: sonnet 4.6 + duck: gpt-5.4 → audit: opus 4.6 for models)

Summary

The two blocking findings from cycle 1 (central-checkout fail-safety and arXiv http:// URLs) have been correctly resolved by dropping the central checkout entirely and switching to a per-repo model. However, the PR cannot merge (CONFLICTING state), CodeQL is still in progress, and the prior CHANGES_REQUESTED review has not been dismissed. One new minor issue: the Phase 8 step-summary template still references the now-removed .petry-standards/ path — it should use {{ inputs.sources_file }} instead.

Findings

Major

  • [major] gate-failure — PR is in CONFLICTING merge state and cannot be merged until rebase/merge conflicts are resolved.

Minor

  • [minor] .github/workflows/feature-ideation-reusable.yml:741 — Phase 8 step-summary template tells Mary "if a high-value source kept coming up but is NOT listed in .petry-standards/standards/feature-ideation-sources.md" — but .petry-standards/ is no longer checked out (the central checkout was removed in this PR). The reference should be updated to ${{ inputs.sources_file }} or the repo-local path so the instruction is accurate.
  • [minor] standards/workflows/feature-ideation.yml:84 — Caller stub template calls the reusable workflow at @v1 — a mutable tag. The prior review flagged this; it remains unaddressed. Impact is low since the content is documentation/markdown consumed as AI context rather than executed code, but it is inconsistent with how other Actions in this workflow are pinned to commit SHAs.

Info

  • [info] ci-pending — CodeQL "Analyze (actions)" check was still IN_PROGRESS at review time; CI is not fully green.
  • [info] prior-review-open — CodeRabbit's CHANGES_REQUESTED review (from commit 2732d4b) has not been dismissed. GitHub may block merge depending on branch protection rules.
  • [info] correctness.github/workflows/feature-ideation-reusable.yml:88actions: read permission added to gather-signals job is correctly scoped for gh run list. The last_successful_run ISO-8601 value is passed to jq via --arg (no injection risk) and used only as prompt context. The macOS/Linux date fallback is correct defensive coding for non-Ubuntu runners.

CI status

CodeQL "Analyze (actions)" was IN_PROGRESS at review time. PR merge state is DIRTY (conflicts present).


Reviewed by the don-petry PR-review cascade (triage: haiku 4.5 → deep: sonnet 4.6 + duck: gpt-5.4 → audit: opus 4.6). Reply with @don-petry if you need a human.

@don-petry

Copy link
Copy Markdown
Contributor Author

Review — fix requested (cycle 2/3)

The automated review identified the following issues. Please address each one:

Findings to fix

  • [major] (no file) — PR is in CONFLICTING merge state and cannot be merged until rebase/merge conflicts are resolved.
  • [minor] .github/workflows/feature-ideation-reusable.yml:741 — Phase 8 step-summary template references .petry-standards/standards/feature-ideation-sources.md but .petry-standards/ is no longer checked out. Update to ${{ inputs.sources_file }} or the repo-local path.
  • [minor] standards/workflows/feature-ideation.yml:84 — Caller stub calls the reusable workflow at @v1 (mutable tag), flagged in the prior review and still unaddressed. Pin to a commit SHA to be consistent with other Actions in this workflow.

Additional tasks

  1. Resolve all unresolved review thread comments from other reviewers
  2. Ensure all CI checks pass after your changes
  3. Rebase on main if the branch is behind
  4. Do NOT modify files unrelated to the findings above

The review cascade will automatically re-review after new commits are pushed.

…st successful run

Source list (addresses all Copilot/CodeRabbit/don-petry review threads):
- Add standards/feature-ideation-sources.md as a starter template; each
  adopting repo copies it to .github/feature-ideation-sources.md and owns
  it independently (no cross-repo checkout).
- Add sources_file input to the reusable workflow (default:
  .github/feature-ideation-sources.md). Phase 2 prompt reads the repo-
  local file; falls back to open web search if absent.
- Fix three arXiv RSS feed URLs from http:// to https://.
- Update propagation wording in ci-standards.md to reflect per-repo
  ownership and v1 tag model.
- Pin caller stub reusable ref from mutable @v1 to commit SHA ae9709f # v1.
- Add actions: read to gather-signals permissions and caller stub template
  (required for gh run list in same repo).

Feed checkpoint (new — avoids re-reviewing same content every week):
- collect-signals.sh: query gh run list --status=success --limit=1 to
  resolve the previous successful run timestamp; fall back to 30 days ago
  on first run or after a long outage.
- compose-signals.sh: add last_successful_run as arg 10 (schema_version
  shifts to arg 11, truncation_warnings to arg 12).
- signals.schema.json: add last_successful_run field; bump schema version
  1.0.0 → 1.1.0 (SCHEMA_VERSION constant updated in lockstep per bats test).
- Test fixtures (populated, empty-repo, truncated): add last_successful_run
  and bump schema_version to 1.1.0.
- Phase 2 prompt: instruct Mary to filter feed entries to those published
  after last_successful_run; bypass checkpoint if >60 days old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@don-petry don-petry force-pushed the feat/feature-ideation-sources-list branch from 4147369 to 76d1f75 Compare April 16, 2026 17:56
coderabbitai[bot]
coderabbitai Bot previously approved these changes Apr 16, 2026
@don-petry don-petry dismissed coderabbitai[bot]’s stale review April 16, 2026 17:57

All findings addressed: arXiv HTTPS fixed, central-repo checkout replaced with per-repo sources_file input, continue-on-error moot (checkout removed), propagation wording updated, caller stub SHA-pinned. Feed checkpoint (last_successful_run) added to signals.json contract.

@don-petry don-petry enabled auto-merge (squash) April 16, 2026 17:57
…un fallback

The gh stub used in bats tests returns raw fixture JSON without applying
--jq filters, so the captured last_successful_run value was a JSON array
instead of an ISO-8601 timestamp. Add a grep -qE '^[0-9]{4}-...' guard
that falls back to the 30-day default whenever the output is not a valid
date-time string, keeping all existing bats tests green without requiring
every test script to stub the new gh run list call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The feed-checkpoint `gh run list` call added in the previous commit is
now the *first* gh invocation, so every manually-built stub script in
collect-signals.bats needs a corresponding first entry.

- Prepend run-list-last-success.txt to all 5 manual script builders
  (auth-failure, graphql-errors, bot-only-truncation,
  discussions-truncated, no-ideas-category)
- Fix date fallback format: append T00:00:00Z to date_days_ago output
  so the JSON Schema format:date-time constraint is satisfied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@don-petry don-petry left a comment

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.

Automated review — NEEDS HUMAN REVIEW

Risk: MEDIUM
Reviewed commit: 0425a174a1e9f8c4b76b4a74477d13f3ce843f11
Cascade: triage → deep (see triage: haiku 4.5 → deep: sonnet 4.6 + duck: gpt-5.4 → audit: opus 4.6 for models)

Summary

CI is broken: compose-signals.bats tests 19–23 all fail because the test file was not updated when compose-signals.sh arity changed from 11 to 12 args. The branch is also behind main. No security concerns — the new last_successful_run field is safely handled via ISO-8601 validation and jq --arg.

Findings

Major

  • [major] test/workflows/feature-ideation/compose-signals.bats — compose-signals.bats tests 19–23 fail with '[compose-signals] expected 12 args, got 11'. The compose-signals.sh function signature was bumped to 12 positional args (inserting last_successful_run at position 10) but the unit tests in test/workflows/feature-ideation/compose-signals.bats still call it with 11 args. All compose unit tests are broken. Fix: update each compose_signals call in compose-signals.bats to pass a dummy ISO-8601 last_successful_run arg (e.g. '2026-03-01T00:00:00Z') in the 10th position and shift schema_version to 11th and truncation_warnings to 12th.

Minor

  • [minor] Branch is BEHIND main (mergeStateStatus: BEHIND). Rebase or merge main into the branch before merging.
  • [minor] .github/workflows/feature-ideation-reusable.yml:741 — Phase 8 step-summary template still references '.petry-standards/standards/feature-ideation-sources.md'. The cross-repo checkout was removed in this PR, making that path unreachable on the runner. The reference should be updated to use '${{ inputs.sources_file }}' or the repo-local path. This was flagged in cycle 2 and does not appear to be addressed in the current diff.

Info

  • [info] collect-signals.sh — last_successful_run ISO-8601 validation guard (grep -qE '^[0-9]{4}-[0-9]{2}-[0-9]{2}T') is a reasonable defence against the test-stub format mismatch. The T00:00:00Z suffix appended to the date_days_ago fallback correctly satisfies the JSON Schema format:date-time constraint.
  • [info] jq receives last_successful_run via --arg (not string interpolation), eliminating any injection risk. The actions: read permission is correctly scoped to the gather-signals job for gh run list use.
  • [info] standards/workflows/feature-ideation.yml — Caller stub now pins reusable workflow ref to commit SHA ae9709f # v1 — the mutable-tag finding from cycles 1 and 2 is resolved.

CI status

CI is failing. compose-signals.bats tests 19–23 fail due to arity mismatch (11 args passed, 12 expected after the last_successful_run parameter was added). Branch is also behind main.


Reviewed by the don-petry PR-review cascade (triage: haiku 4.5 → deep: sonnet 4.6 + duck: gpt-5.4 → audit: opus 4.6). Reply with @don-petry if you need a human.

@don-petry

Copy link
Copy Markdown
Contributor Author

Review — fix requested (cycle 3/3)

The automated review identified the following issues. Please address each one:

Findings to fix

  • [major] test/workflows/feature-ideation/compose-signals.bats — compose-signals.bats tests 19–23 fail with '[compose-signals] expected 12 args, got 11'. The compose-signals.sh function signature was bumped to 12 positional args (inserting last_successful_run at position 10) but the unit tests still call it with 11 args. Fix: update each compose_signals call in compose-signals.bats to pass a dummy ISO-8601 last_successful_run arg (e.g. '2026-03-01T00:00:00Z') in the 10th position and shift schema_version to 11th and truncation_warnings to 12th.
  • [minor] .github/workflows/feature-ideation-reusable.yml:741 — Phase 8 step-summary template still references '.petry-standards/standards/feature-ideation-sources.md'. The cross-repo checkout was removed in this PR, making that path unreachable on the runner. Update the reference to use ${{ inputs.sources_file }} or the repo-local path.
  • [minor] Branch is BEHIND main. Rebase or merge main into the branch before merging.

Additional tasks

  1. Resolve all unresolved review thread comments from other reviewers
  2. Ensure all CI checks pass after your changes
  3. Rebase on main if the branch is behind
  4. Do NOT modify files unrelated to the findings above

The review cascade will automatically re-review after new commits are pushed.

All compose_signals invocations now pass last_successful_run as
the new arg 10, shifting schema_version to 11 and
truncation_warnings to 12. Also adds last_successful_run to the
required-fields assertion in the empty-inputs test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
coderabbitai[bot]
coderabbitai Bot previously requested changes Apr 17, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
.github/scripts/feature-ideation/lib/compose-signals.sh (1)

50-58: 🧹 Nitpick | 🔵 Trivial

Minor: arg #%d in the validation error message no longer matches positional indices.

The validation loop iterates the 8 JSON inputs (open_issues … bug_reports, truncation_warnings) and increments idx from 1. With the new signature, truncation_warnings is positional arg $12 but a failure there will report arg #8``. This was already misleading before the signature change, but it is more confusing now that non-JSON args (repo, `scan_date`, `last_successful_run`, `schema_version`) are interleaved. Consider mapping `idx` to the documented positional number (e.g. label by name) to aid debugging.

♻️ Proposed tweak
-  local idx=0
-  for input in "$open_issues" "$closed_issues" "$ideas_discussions" "$releases" \
-               "$merged_prs" "$feature_requests" "$bug_reports" "$truncation_warnings"; do
-    idx=$((idx + 1))
-    if ! printf '%s' "$input" | jq -e . >/dev/null 2>&1; then
-      printf '[compose-signals] arg #%d is not valid JSON: %s\n' "$idx" "${input:0:120}" >&2
+  local name
+  for pair in "open_issues:$open_issues" "closed_issues:$closed_issues" \
+              "ideas_discussions:$ideas_discussions" "releases:$releases" \
+              "merged_prs:$merged_prs" "feature_requests:$feature_requests" \
+              "bug_reports:$bug_reports" "truncation_warnings:$truncation_warnings"; do
+    name="${pair%%:*}"
+    input="${pair#*:}"
+    if ! printf '%s' "$input" | jq -e . >/dev/null 2>&1; then
+      printf '[compose-signals] %s is not valid JSON: %s\n' "$name" "${input:0:120}" >&2
       return 65  # EX_DATAERR
     fi
   done
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/scripts/feature-ideation/lib/compose-signals.sh around lines 50 -
58, The error message reports a misleading "arg #%d" because the loop uses a
simple idx over the eight JSON variables (open_issues, closed_issues,
ideas_discussions, releases, merged_prs, feature_requests, bug_reports,
truncation_warnings) while other positional args exist; fix it by mapping each
iterated variable to its documented positional label or actual positional number
before printing: create a parallel array of names or positional indices (e.g.
names=("open_issues" "closed_issues" ...)) and when a validation fails use that
name (or compute the real positional index) in the printf instead of idx; update
the printf call that references idx and "${input:0:120}" to use the mapped
name/position so the error shows the correct argument identifier.
test/workflows/feature-ideation/compose-signals.bats (1)

94-103: 🧹 Nitpick | 🔵 Trivial

Consider asserting last_successful_run round-trips verbatim.

scan_date and repo are checked for exact round-trip, but the new last_successful_run argument is passed in several tests yet never asserted on the output. Since this value drives the Phase 2 feed-checkpoint behavior, a one-line assertion would catch any future refactor that silently drops or reformats it.

Proposed addition
 `@test` "compose: scan_date and repo round-trip exactly" {
   run compose_signals \
     '[]' '[]' '[]' '[]' '[]' '[]' '[]' \
     'octocat/hello-world' '2030-01-15T12:34:56Z' '2029-12-15T12:34:56Z' '1.0.0' '[]'
   [ "$status" -eq 0 ]
   d=$(printf '%s' "$output" | jq -r '.scan_date')
   r=$(printf '%s' "$output" | jq -r '.repo')
+  l=$(printf '%s' "$output" | jq -r '.last_successful_run')
   [ "$d" = "2030-01-15T12:34:56Z" ]
   [ "$r" = "octocat/hello-world" ]
+  [ "$l" = "2029-12-15T12:34:56Z" ]
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/workflows/feature-ideation/compose-signals.bats` around lines 94 - 103,
The test "compose: scan_date and repo round-trip exactly" calls compose_signals
with a last_successful_run value but never asserts it; add a one-line assertion
that extracts '.last_successful_run' from the command output (e.g., l=$(printf
'%s' "$output" | jq -r '.last_successful_run')) and assert [ "$l" =
"2029-12-15T12:34:56Z" ] so compose_signals (and the output JSON) round-trips
last_successful_run verbatim.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/scripts/feature-ideation/collect-signals.sh:
- Around line 81-88: The code hardcodes the workflow filename in the gh run list
call (the variable last_successful_run using --workflow="feature-ideation.yml"),
which causes silent fallback to 30 days if a repo renames the workflow; change
the script to accept a workflow filename via an env var (e.g. use WORKFLOW_FILE
or GITHUB_WORKFLOW_REF) and use that when calling gh run list instead of the
hardcoded string, and add a clear stderr warning (printf ... >&2) when the gh
query returns empty and you’re about to use the 30-day fallback so
misconfiguration vs first-run is distinguishable; also add an inline comment
documenting the new WORKFLOW_FILE env convention so callers know to set it.
- Around line 93-100: The current fallback masks failures when obtaining
last_successful_run; capture the command's stderr instead of discarding it so
you can distinguish a genuine missing checkpoint from an auth/network error.
Change the logic that sets last_successful_run (the command that currently has
2>/dev/null || true) to capture both stdout (into last_successful_run) and
stderr (into, e.g., last_successful_run_err), then keep the existing regex check
on last_successful_run; if the value is unusable and last_successful_run_err is
non-empty, write a clear diagnostic to stderr (including
last_successful_run_err) before falling back to date_days_ago and setting the
30-day checkpoint, so operators can see permission/token/network failures while
preserving the existing fallback behavior.

In `@standards/workflows/feature-ideation.yml`:
- Around line 101-106: Update the commented guidance for the default
"sources_file" entry so it accurately tells users to both uncomment and edit if
they want a different path—specifically change the current line that reads
"override only if you store the file elsewhere" to something like "uncomment and
change the path only if you store the file elsewhere" next to the commented
"sources_file: '.github/feature-ideation-sources.md'" so intent is clear when
modifying the sources_file default.

---

Outside diff comments:
In @.github/scripts/feature-ideation/lib/compose-signals.sh:
- Around line 50-58: The error message reports a misleading "arg #%d" because
the loop uses a simple idx over the eight JSON variables (open_issues,
closed_issues, ideas_discussions, releases, merged_prs, feature_requests,
bug_reports, truncation_warnings) while other positional args exist; fix it by
mapping each iterated variable to its documented positional label or actual
positional number before printing: create a parallel array of names or
positional indices (e.g. names=("open_issues" "closed_issues" ...)) and when a
validation fails use that name (or compute the real positional index) in the
printf instead of idx; update the printf call that references idx and
"${input:0:120}" to use the mapped name/position so the error shows the correct
argument identifier.

In `@test/workflows/feature-ideation/compose-signals.bats`:
- Around line 94-103: The test "compose: scan_date and repo round-trip exactly"
calls compose_signals with a last_successful_run value but never asserts it; add
a one-line assertion that extracts '.last_successful_run' from the command
output (e.g., l=$(printf '%s' "$output" | jq -r '.last_successful_run')) and
assert [ "$l" = "2029-12-15T12:34:56Z" ] so compose_signals (and the output
JSON) round-trips last_successful_run verbatim.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: d8d97574-2df8-42f4-9968-0794cf0bab98

📥 Commits

Reviewing files that changed from the base of the PR and between 2732d4b and 15045be.

📒 Files selected for processing (13)
  • .github/schemas/signals.schema.json
  • .github/scripts/feature-ideation/collect-signals.sh
  • .github/scripts/feature-ideation/lib/compose-signals.sh
  • .github/workflows/feature-ideation-reusable.yml
  • standards/ci-standards.md
  • standards/feature-ideation-sources.md
  • standards/workflows/feature-ideation.yml
  • test/workflows/feature-ideation/collect-signals.bats
  • test/workflows/feature-ideation/compose-signals.bats
  • test/workflows/feature-ideation/fixtures/expected/empty-repo.signals.json
  • test/workflows/feature-ideation/fixtures/expected/populated.signals.json
  • test/workflows/feature-ideation/fixtures/expected/truncated.signals.json
  • test/workflows/feature-ideation/fixtures/gh-responses/run-list-last-success.txt

Comment thread .github/scripts/feature-ideation/collect-signals.sh Outdated
Comment thread .github/scripts/feature-ideation/collect-signals.sh
Comment thread standards/workflows/feature-ideation.yml Outdated
- collect-signals.sh: use WORKFLOW_FILE env var (default: feature-ideation.yml)
  so repos that rename their caller stub can override without a code change;
  capture gh run list stderr in a temp file and log it when the fallback is
  triggered so auth/network failures are distinguishable from first-run
- feature-ideation-reusable.yml: clarify propagation comment — changes reach
  @v1 stubs only after the v1 tag is bumped, not on every next run
- ci-standards.md: align Tier-1 table wording with the @v1 tag-bump model
- standards/workflows/feature-ideation.yml: reword sources_file comment to
  make clear users must uncomment AND change the path for non-default locations;
  show a non-default example path to reduce ambiguity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@don-petry don-petry dismissed coderabbitai[bot]’s stale review April 17, 2026 02:26

All findings addressed: hardcoded workflow filename replaced with ${WORKFLOW_FILE:-feature-ideation.yml}, stderr capture added for diagnostics, propagation wording corrected across workflow/standards files, sources_file comment clarified.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Apr 17, 2026

@don-petry don-petry left a comment

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.

Automated review — NEEDS HUMAN REVIEW

Risk: MEDIUM
Reviewed commit: bc8e529ea0f7a9a081d5b3bf829af9e5c8045b0a
Cascade: triage → deep (see triage: haiku 4.5 → deep: sonnet 4.6 + duck: gpt-5.4 → audit: opus 4.6 for models)

Summary

CI is failing: the SonarCloud Code Analysis external check reports FAILURE on the current HEAD (bc8e529). All GitHub Actions checks pass (bats, ShellCheck, CodeQL, AgentShield all green), meaning the compose-signals arity fix and prior issues are resolved — but the SonarCloud quality gate is a blocking failure. Branch is also BEHIND main and must be rebased before merge.

Findings

Major

  • [major] — SonarCloud Code Analysis external check is FAILURE on HEAD bc8e529ea0f7a9a081d5b3bf829af9e5c8045b0a. This is a required CI gate. All GitHub Actions checks (bats, ShellCheck, CodeQL, AgentShield, Lint) pass — only the external SonarCloud Code Analysis check fails. PR cannot be approved until this is resolved.

Minor

  • [minor] — Branch is BEHIND main (mergeStateStatus: BEHIND). Author must rebase or merge main before the PR can cleanly land.
  • [minor] .github/workflows/feature-ideation.yml:49 — New file calls the reusable workflow at the mutable branch ref @feat/feature-ideation-sources-list. After this branch is merged and deleted, the ref will be invalid. Should be updated to @main or a commit SHA before merging. (Impact is low — workflow is workflow_dispatch-only with dry_run: true hardcoded.)

Info

  • [info] .github/scripts/feature-ideation/collect-signals.sh:83last_successful_run value is passed to jq via --arg (not string interpolation) and used only as prompt context — no injection risk. The WORKFLOW_FILE env var is set by the workflow, not by untrusted user input.
  • [info] .github/workflows/feature-ideation-reusable.yml:109actions: read permission added to gather-signals job is correctly minimal and scoped for the gh run list call. No privilege escalation risk.
  • [info] — Prior cycle-2 issue (compose-signals.bats arity mismatch) is resolved — Feature Ideation Tests (bats) CI check shows SUCCESS. Prior arXiv http:// URL concern resolved — current diff uses https://export.arxiv.org RSS URLs.
  • [info] .github/scripts/feature-ideation/collect-signals.sh:100 — ISO-8601 validation guard and 30-day fallback are correct. The T00:00:00Z suffix appended to date_days_ago fallback satisfies the JSON Schema format:date-time constraint.

CI status

  • SonarCloud Code Analysis: FAILURE (blocking external check)
  • bats, ShellCheck, CodeQL, AgentShield, Lint: PASS

Reviewed by the don-petry PR-review cascade (triage: haiku 4.5 → deep: sonnet 4.6 + duck: gpt-5.4 → audit: opus 4.6). Reply with @don-petry if you need a human.

DJ and others added 3 commits April 17, 2026 09:52
The format() expression with backtick literals inside a GHA expression
caused a YAML mapping-value syntax error at parse time. Replaced with
a plain env var SOURCES_FILE_PATH + shell-style conditional in the prompt
text — no GHA expressions inside the multiline prompt string, fully
YAML-safe and under the 200-char line limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds the Feature Research & Ideation workflow to the .github repo itself,
making it a BMAD-enabled consumer of its own reusable pipeline.

Key configuration:
- project_context: org-level DevX/tooling repo (CI standards, reusable
  workflows, BMAD framework, agent security)
- sources_file: 'standards/feature-ideation-sources.md' — the template
  lives right here, so no copy needed
- dry_run defaults to false (use workflow_dispatch input to enable)
- actions: read permission for feed checkpoint

Note: uses: SHA points to current v1. After this PR merges, bump the
v1 tag to the new merge commit and update the SHA here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@don-petry don-petry disabled auto-merge April 17, 2026 17:03
@don-petry don-petry merged commit ee22b42 into main Apr 17, 2026
21 checks passed
@don-petry don-petry deleted the feat/feature-ideation-sources-list branch April 17, 2026 17:03
don-petry added a commit that referenced this pull request Jun 8, 2026
)

* feat(feature-ideation): per-repo source list + feed checkpoint via last successful run

Source list (addresses all Copilot/CodeRabbit/don-petry review threads):
- Add standards/feature-ideation-sources.md as a starter template; each
  adopting repo copies it to .github/feature-ideation-sources.md and owns
  it independently (no cross-repo checkout).
- Add sources_file input to the reusable workflow (default:
  .github/feature-ideation-sources.md). Phase 2 prompt reads the repo-
  local file; falls back to open web search if absent.
- Fix three arXiv RSS feed URLs from http:// to https://.
- Update propagation wording in ci-standards.md to reflect per-repo
  ownership and v1 tag model.
- Pin caller stub reusable ref from mutable @v1 to commit SHA ae9709f # v1.
- Add actions: read to gather-signals permissions and caller stub template
  (required for gh run list in same repo).

Feed checkpoint (new — avoids re-reviewing same content every week):
- collect-signals.sh: query gh run list --status=success --limit=1 to
  resolve the previous successful run timestamp; fall back to 30 days ago
  on first run or after a long outage.
- compose-signals.sh: add last_successful_run as arg 10 (schema_version
  shifts to arg 11, truncation_warnings to arg 12).
- signals.schema.json: add last_successful_run field; bump schema version
  1.0.0 → 1.1.0 (SCHEMA_VERSION constant updated in lockstep per bats test).
- Test fixtures (populated, empty-repo, truncated): add last_successful_run
  and bump schema_version to 1.1.0.
- Phase 2 prompt: instruct Mary to filter feed entries to those published
  after last_successful_run; bypass checkpoint if >60 days old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(feature-ideation): validate ISO-8601 format for last_successful_run fallback

The gh stub used in bats tests returns raw fixture JSON without applying
--jq filters, so the captured last_successful_run value was a JSON array
instead of an ISO-8601 timestamp. Add a grep -qE '^[0-9]{4}-...' guard
that falls back to the 30-day default whenever the output is not a valid
date-time string, keeping all existing bats tests green without requiring
every test script to stub the new gh run list call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(collect-signals): align bats stub order with new gh run list call

The feed-checkpoint `gh run list` call added in the previous commit is
now the *first* gh invocation, so every manually-built stub script in
collect-signals.bats needs a corresponding first entry.

- Prepend run-list-last-success.txt to all 5 manual script builders
  (auth-failure, graphql-errors, bot-only-truncation,
  discussions-truncated, no-ideas-category)
- Fix date fallback format: append T00:00:00Z to date_days_ago output
  so the JSON Schema format:date-time constraint is satisfied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compose-signals.bats): update call sites to 12-arg signature

All compose_signals invocations now pass last_successful_run as
the new arg 10, shifting schema_version to 11 and
truncation_warnings to 12. Also adds last_successful_run to the
required-fields assertion in the empty-inputs test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): address CodeRabbit and Copilot review comments

- collect-signals.sh: use WORKFLOW_FILE env var (default: feature-ideation.yml)
  so repos that rename their caller stub can override without a code change;
  capture gh run list stderr in a temp file and log it when the fallback is
  triggered so auth/network failures are distinguishable from first-run
- feature-ideation-reusable.yml: clarify propagation comment — changes reach
  @v1 stubs only after the v1 tag is bumped, not on every next run
- ci-standards.md: align Tier-1 table wording with the @v1 tag-bump model
- standards/workflows/feature-ideation.yml: reword sources_file comment to
  make clear users must uncomment AND change the path for non-default locations;
  show a non-default example path to reduce ambiguity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add self-test feature-ideation stub for dry-run validation

* fix: trailing newline + clean up stub

* fix: pin reusable workflow ref to commit SHA (SonarCloud)

* chore: remove temporary test stub (not for main)

* fix(reusable): guard against empty sources_file in Phase 2 prompt

If a caller passes sources_file: '' the prompt previously rendered a
bare 'Read: ' instruction. Now uses a GitHub Actions expression to
branch: non-empty value emits the Read instruction; empty/omitted
emits a clear fallback note directing Mary to open web search and log
a warning in the step summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): move sources_file expression to env var to respect line-length

The format() expression was 241 chars, over the 200-char yamllint limit.
Moving it to SOURCES_INSTRUCTION in the step env block (where the
expression is still valid) and referencing $SOURCES_INSTRUCTION in the
prompt string brings all lines under 200 chars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): resolve YAML syntax error in sources_file prompt guard

The format() expression with backtick literals inside a GHA expression
caused a YAML mapping-value syntax error at parse time. Replaced with
a plain env var SOURCES_FILE_PATH + shell-style conditional in the prompt
text — no GHA expressions inside the multiline prompt string, fully
YAML-safe and under the 200-char line limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(dotgithub): add feature-ideation caller stub for .github self-test

Adds the Feature Research & Ideation workflow to the .github repo itself,
making it a BMAD-enabled consumer of its own reusable pipeline.

Key configuration:
- project_context: org-level DevX/tooling repo (CI standards, reusable
  workflows, BMAD framework, agent security)
- sources_file: 'standards/feature-ideation-sources.md' — the template
  lives right here, so no copy needed
- dry_run defaults to false (use workflow_dispatch input to enable)
- actions: read permission for feed checkpoint

Note: uses: SHA points to current v1. After this PR merges, bump the
v1 tag to the new merge commit and update the SHA here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
don-petry added a commit that referenced this pull request Jun 8, 2026
)

* feat(feature-ideation): per-repo source list + feed checkpoint via last successful run

Source list (addresses all Copilot/CodeRabbit/don-petry review threads):
- Add standards/feature-ideation-sources.md as a starter template; each
  adopting repo copies it to .github/feature-ideation-sources.md and owns
  it independently (no cross-repo checkout).
- Add sources_file input to the reusable workflow (default:
  .github/feature-ideation-sources.md). Phase 2 prompt reads the repo-
  local file; falls back to open web search if absent.
- Fix three arXiv RSS feed URLs from http:// to https://.
- Update propagation wording in ci-standards.md to reflect per-repo
  ownership and v1 tag model.
- Pin caller stub reusable ref from mutable @v1 to commit SHA ae9709f # v1.
- Add actions: read to gather-signals permissions and caller stub template
  (required for gh run list in same repo).

Feed checkpoint (new — avoids re-reviewing same content every week):
- collect-signals.sh: query gh run list --status=success --limit=1 to
  resolve the previous successful run timestamp; fall back to 30 days ago
  on first run or after a long outage.
- compose-signals.sh: add last_successful_run as arg 10 (schema_version
  shifts to arg 11, truncation_warnings to arg 12).
- signals.schema.json: add last_successful_run field; bump schema version
  1.0.0 → 1.1.0 (SCHEMA_VERSION constant updated in lockstep per bats test).
- Test fixtures (populated, empty-repo, truncated): add last_successful_run
  and bump schema_version to 1.1.0.
- Phase 2 prompt: instruct Mary to filter feed entries to those published
  after last_successful_run; bypass checkpoint if >60 days old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(feature-ideation): validate ISO-8601 format for last_successful_run fallback

The gh stub used in bats tests returns raw fixture JSON without applying
--jq filters, so the captured last_successful_run value was a JSON array
instead of an ISO-8601 timestamp. Add a grep -qE '^[0-9]{4}-...' guard
that falls back to the 30-day default whenever the output is not a valid
date-time string, keeping all existing bats tests green without requiring
every test script to stub the new gh run list call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(collect-signals): align bats stub order with new gh run list call

The feed-checkpoint `gh run list` call added in the previous commit is
now the *first* gh invocation, so every manually-built stub script in
collect-signals.bats needs a corresponding first entry.

- Prepend run-list-last-success.txt to all 5 manual script builders
  (auth-failure, graphql-errors, bot-only-truncation,
  discussions-truncated, no-ideas-category)
- Fix date fallback format: append T00:00:00Z to date_days_ago output
  so the JSON Schema format:date-time constraint is satisfied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compose-signals.bats): update call sites to 12-arg signature

All compose_signals invocations now pass last_successful_run as
the new arg 10, shifting schema_version to 11 and
truncation_warnings to 12. Also adds last_successful_run to the
required-fields assertion in the empty-inputs test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): address CodeRabbit and Copilot review comments

- collect-signals.sh: use WORKFLOW_FILE env var (default: feature-ideation.yml)
  so repos that rename their caller stub can override without a code change;
  capture gh run list stderr in a temp file and log it when the fallback is
  triggered so auth/network failures are distinguishable from first-run
- feature-ideation-reusable.yml: clarify propagation comment — changes reach
  @v1 stubs only after the v1 tag is bumped, not on every next run
- ci-standards.md: align Tier-1 table wording with the @v1 tag-bump model
- standards/workflows/feature-ideation.yml: reword sources_file comment to
  make clear users must uncomment AND change the path for non-default locations;
  show a non-default example path to reduce ambiguity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add self-test feature-ideation stub for dry-run validation

* fix: trailing newline + clean up stub

* fix: pin reusable workflow ref to commit SHA (SonarCloud)

* chore: remove temporary test stub (not for main)

* fix(reusable): guard against empty sources_file in Phase 2 prompt

If a caller passes sources_file: '' the prompt previously rendered a
bare 'Read: ' instruction. Now uses a GitHub Actions expression to
branch: non-empty value emits the Read instruction; empty/omitted
emits a clear fallback note directing Mary to open web search and log
a warning in the step summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): move sources_file expression to env var to respect line-length

The format() expression was 241 chars, over the 200-char yamllint limit.
Moving it to SOURCES_INSTRUCTION in the step env block (where the
expression is still valid) and referencing $SOURCES_INSTRUCTION in the
prompt string brings all lines under 200 chars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): resolve YAML syntax error in sources_file prompt guard

The format() expression with backtick literals inside a GHA expression
caused a YAML mapping-value syntax error at parse time. Replaced with
a plain env var SOURCES_FILE_PATH + shell-style conditional in the prompt
text — no GHA expressions inside the multiline prompt string, fully
YAML-safe and under the 200-char line limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(dotgithub): add feature-ideation caller stub for .github self-test

Adds the Feature Research & Ideation workflow to the .github repo itself,
making it a BMAD-enabled consumer of its own reusable pipeline.

Key configuration:
- project_context: org-level DevX/tooling repo (CI standards, reusable
  workflows, BMAD framework, agent security)
- sources_file: 'standards/feature-ideation-sources.md' — the template
  lives right here, so no copy needed
- dry_run defaults to false (use workflow_dispatch input to enable)
- actions: read permission for feed checkpoint

Note: uses: SHA points to current v1. After this PR merges, bump the
v1 tag to the new merge commit and update the SHA here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
don-petry added a commit that referenced this pull request Jun 8, 2026
)

* feat(feature-ideation): per-repo source list + feed checkpoint via last successful run

Source list (addresses all Copilot/CodeRabbit/don-petry review threads):
- Add standards/feature-ideation-sources.md as a starter template; each
  adopting repo copies it to .github/feature-ideation-sources.md and owns
  it independently (no cross-repo checkout).
- Add sources_file input to the reusable workflow (default:
  .github/feature-ideation-sources.md). Phase 2 prompt reads the repo-
  local file; falls back to open web search if absent.
- Fix three arXiv RSS feed URLs from http:// to https://.
- Update propagation wording in ci-standards.md to reflect per-repo
  ownership and v1 tag model.
- Pin caller stub reusable ref from mutable @v1 to commit SHA ae9709f # v1.
- Add actions: read to gather-signals permissions and caller stub template
  (required for gh run list in same repo).

Feed checkpoint (new — avoids re-reviewing same content every week):
- collect-signals.sh: query gh run list --status=success --limit=1 to
  resolve the previous successful run timestamp; fall back to 30 days ago
  on first run or after a long outage.
- compose-signals.sh: add last_successful_run as arg 10 (schema_version
  shifts to arg 11, truncation_warnings to arg 12).
- signals.schema.json: add last_successful_run field; bump schema version
  1.0.0 → 1.1.0 (SCHEMA_VERSION constant updated in lockstep per bats test).
- Test fixtures (populated, empty-repo, truncated): add last_successful_run
  and bump schema_version to 1.1.0.
- Phase 2 prompt: instruct Mary to filter feed entries to those published
  after last_successful_run; bypass checkpoint if >60 days old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(feature-ideation): validate ISO-8601 format for last_successful_run fallback

The gh stub used in bats tests returns raw fixture JSON without applying
--jq filters, so the captured last_successful_run value was a JSON array
instead of an ISO-8601 timestamp. Add a grep -qE '^[0-9]{4}-...' guard
that falls back to the 30-day default whenever the output is not a valid
date-time string, keeping all existing bats tests green without requiring
every test script to stub the new gh run list call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(collect-signals): align bats stub order with new gh run list call

The feed-checkpoint `gh run list` call added in the previous commit is
now the *first* gh invocation, so every manually-built stub script in
collect-signals.bats needs a corresponding first entry.

- Prepend run-list-last-success.txt to all 5 manual script builders
  (auth-failure, graphql-errors, bot-only-truncation,
  discussions-truncated, no-ideas-category)
- Fix date fallback format: append T00:00:00Z to date_days_ago output
  so the JSON Schema format:date-time constraint is satisfied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compose-signals.bats): update call sites to 12-arg signature

All compose_signals invocations now pass last_successful_run as
the new arg 10, shifting schema_version to 11 and
truncation_warnings to 12. Also adds last_successful_run to the
required-fields assertion in the empty-inputs test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): address CodeRabbit and Copilot review comments

- collect-signals.sh: use WORKFLOW_FILE env var (default: feature-ideation.yml)
  so repos that rename their caller stub can override without a code change;
  capture gh run list stderr in a temp file and log it when the fallback is
  triggered so auth/network failures are distinguishable from first-run
- feature-ideation-reusable.yml: clarify propagation comment — changes reach
  @v1 stubs only after the v1 tag is bumped, not on every next run
- ci-standards.md: align Tier-1 table wording with the @v1 tag-bump model
- standards/workflows/feature-ideation.yml: reword sources_file comment to
  make clear users must uncomment AND change the path for non-default locations;
  show a non-default example path to reduce ambiguity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add self-test feature-ideation stub for dry-run validation

* fix: trailing newline + clean up stub

* fix: pin reusable workflow ref to commit SHA (SonarCloud)

* chore: remove temporary test stub (not for main)

* fix(reusable): guard against empty sources_file in Phase 2 prompt

If a caller passes sources_file: '' the prompt previously rendered a
bare 'Read: ' instruction. Now uses a GitHub Actions expression to
branch: non-empty value emits the Read instruction; empty/omitted
emits a clear fallback note directing Mary to open web search and log
a warning in the step summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): move sources_file expression to env var to respect line-length

The format() expression was 241 chars, over the 200-char yamllint limit.
Moving it to SOURCES_INSTRUCTION in the step env block (where the
expression is still valid) and referencing $SOURCES_INSTRUCTION in the
prompt string brings all lines under 200 chars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): resolve YAML syntax error in sources_file prompt guard

The format() expression with backtick literals inside a GHA expression
caused a YAML mapping-value syntax error at parse time. Replaced with
a plain env var SOURCES_FILE_PATH + shell-style conditional in the prompt
text — no GHA expressions inside the multiline prompt string, fully
YAML-safe and under the 200-char line limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(dotgithub): add feature-ideation caller stub for .github self-test

Adds the Feature Research & Ideation workflow to the .github repo itself,
making it a BMAD-enabled consumer of its own reusable pipeline.

Key configuration:
- project_context: org-level DevX/tooling repo (CI standards, reusable
  workflows, BMAD framework, agent security)
- sources_file: 'standards/feature-ideation-sources.md' — the template
  lives right here, so no copy needed
- dry_run defaults to false (use workflow_dispatch input to enable)
- actions: read permission for feed checkpoint

Note: uses: SHA points to current v1. After this PR merges, bump the
v1 tag to the new merge commit and update the SHA here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
don-petry added a commit that referenced this pull request Jun 8, 2026
)

* feat(feature-ideation): per-repo source list + feed checkpoint via last successful run

Source list (addresses all Copilot/CodeRabbit/don-petry review threads):
- Add standards/feature-ideation-sources.md as a starter template; each
  adopting repo copies it to .github/feature-ideation-sources.md and owns
  it independently (no cross-repo checkout).
- Add sources_file input to the reusable workflow (default:
  .github/feature-ideation-sources.md). Phase 2 prompt reads the repo-
  local file; falls back to open web search if absent.
- Fix three arXiv RSS feed URLs from http:// to https://.
- Update propagation wording in ci-standards.md to reflect per-repo
  ownership and v1 tag model.
- Pin caller stub reusable ref from mutable @v1 to commit SHA ae9709f # v1.
- Add actions: read to gather-signals permissions and caller stub template
  (required for gh run list in same repo).

Feed checkpoint (new — avoids re-reviewing same content every week):
- collect-signals.sh: query gh run list --status=success --limit=1 to
  resolve the previous successful run timestamp; fall back to 30 days ago
  on first run or after a long outage.
- compose-signals.sh: add last_successful_run as arg 10 (schema_version
  shifts to arg 11, truncation_warnings to arg 12).
- signals.schema.json: add last_successful_run field; bump schema version
  1.0.0 → 1.1.0 (SCHEMA_VERSION constant updated in lockstep per bats test).
- Test fixtures (populated, empty-repo, truncated): add last_successful_run
  and bump schema_version to 1.1.0.
- Phase 2 prompt: instruct Mary to filter feed entries to those published
  after last_successful_run; bypass checkpoint if >60 days old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(feature-ideation): validate ISO-8601 format for last_successful_run fallback

The gh stub used in bats tests returns raw fixture JSON without applying
--jq filters, so the captured last_successful_run value was a JSON array
instead of an ISO-8601 timestamp. Add a grep -qE '^[0-9]{4}-...' guard
that falls back to the 30-day default whenever the output is not a valid
date-time string, keeping all existing bats tests green without requiring
every test script to stub the new gh run list call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(collect-signals): align bats stub order with new gh run list call

The feed-checkpoint `gh run list` call added in the previous commit is
now the *first* gh invocation, so every manually-built stub script in
collect-signals.bats needs a corresponding first entry.

- Prepend run-list-last-success.txt to all 5 manual script builders
  (auth-failure, graphql-errors, bot-only-truncation,
  discussions-truncated, no-ideas-category)
- Fix date fallback format: append T00:00:00Z to date_days_ago output
  so the JSON Schema format:date-time constraint is satisfied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compose-signals.bats): update call sites to 12-arg signature

All compose_signals invocations now pass last_successful_run as
the new arg 10, shifting schema_version to 11 and
truncation_warnings to 12. Also adds last_successful_run to the
required-fields assertion in the empty-inputs test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): address CodeRabbit and Copilot review comments

- collect-signals.sh: use WORKFLOW_FILE env var (default: feature-ideation.yml)
  so repos that rename their caller stub can override without a code change;
  capture gh run list stderr in a temp file and log it when the fallback is
  triggered so auth/network failures are distinguishable from first-run
- feature-ideation-reusable.yml: clarify propagation comment — changes reach
  @v1 stubs only after the v1 tag is bumped, not on every next run
- ci-standards.md: align Tier-1 table wording with the @v1 tag-bump model
- standards/workflows/feature-ideation.yml: reword sources_file comment to
  make clear users must uncomment AND change the path for non-default locations;
  show a non-default example path to reduce ambiguity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add self-test feature-ideation stub for dry-run validation

* fix: trailing newline + clean up stub

* fix: pin reusable workflow ref to commit SHA (SonarCloud)

* chore: remove temporary test stub (not for main)

* fix(reusable): guard against empty sources_file in Phase 2 prompt

If a caller passes sources_file: '' the prompt previously rendered a
bare 'Read: ' instruction. Now uses a GitHub Actions expression to
branch: non-empty value emits the Read instruction; empty/omitted
emits a clear fallback note directing Mary to open web search and log
a warning in the step summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): move sources_file expression to env var to respect line-length

The format() expression was 241 chars, over the 200-char yamllint limit.
Moving it to SOURCES_INSTRUCTION in the step env block (where the
expression is still valid) and referencing $SOURCES_INSTRUCTION in the
prompt string brings all lines under 200 chars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): resolve YAML syntax error in sources_file prompt guard

The format() expression with backtick literals inside a GHA expression
caused a YAML mapping-value syntax error at parse time. Replaced with
a plain env var SOURCES_FILE_PATH + shell-style conditional in the prompt
text — no GHA expressions inside the multiline prompt string, fully
YAML-safe and under the 200-char line limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(dotgithub): add feature-ideation caller stub for .github self-test

Adds the Feature Research & Ideation workflow to the .github repo itself,
making it a BMAD-enabled consumer of its own reusable pipeline.

Key configuration:
- project_context: org-level DevX/tooling repo (CI standards, reusable
  workflows, BMAD framework, agent security)
- sources_file: 'standards/feature-ideation-sources.md' — the template
  lives right here, so no copy needed
- dry_run defaults to false (use workflow_dispatch input to enable)
- actions: read permission for feed checkpoint

Note: uses: SHA points to current v1. After this PR merges, bump the
v1 tag to the new merge commit and update the SHA here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
don-petry added a commit that referenced this pull request Jun 8, 2026
)

* feat(feature-ideation): per-repo source list + feed checkpoint via last successful run

Source list (addresses all Copilot/CodeRabbit/don-petry review threads):
- Add standards/feature-ideation-sources.md as a starter template; each
  adopting repo copies it to .github/feature-ideation-sources.md and owns
  it independently (no cross-repo checkout).
- Add sources_file input to the reusable workflow (default:
  .github/feature-ideation-sources.md). Phase 2 prompt reads the repo-
  local file; falls back to open web search if absent.
- Fix three arXiv RSS feed URLs from http:// to https://.
- Update propagation wording in ci-standards.md to reflect per-repo
  ownership and v1 tag model.
- Pin caller stub reusable ref from mutable @v1 to commit SHA ae9709f # v1.
- Add actions: read to gather-signals permissions and caller stub template
  (required for gh run list in same repo).

Feed checkpoint (new — avoids re-reviewing same content every week):
- collect-signals.sh: query gh run list --status=success --limit=1 to
  resolve the previous successful run timestamp; fall back to 30 days ago
  on first run or after a long outage.
- compose-signals.sh: add last_successful_run as arg 10 (schema_version
  shifts to arg 11, truncation_warnings to arg 12).
- signals.schema.json: add last_successful_run field; bump schema version
  1.0.0 → 1.1.0 (SCHEMA_VERSION constant updated in lockstep per bats test).
- Test fixtures (populated, empty-repo, truncated): add last_successful_run
  and bump schema_version to 1.1.0.
- Phase 2 prompt: instruct Mary to filter feed entries to those published
  after last_successful_run; bypass checkpoint if >60 days old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(feature-ideation): validate ISO-8601 format for last_successful_run fallback

The gh stub used in bats tests returns raw fixture JSON without applying
--jq filters, so the captured last_successful_run value was a JSON array
instead of an ISO-8601 timestamp. Add a grep -qE '^[0-9]{4}-...' guard
that falls back to the 30-day default whenever the output is not a valid
date-time string, keeping all existing bats tests green without requiring
every test script to stub the new gh run list call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(collect-signals): align bats stub order with new gh run list call

The feed-checkpoint `gh run list` call added in the previous commit is
now the *first* gh invocation, so every manually-built stub script in
collect-signals.bats needs a corresponding first entry.

- Prepend run-list-last-success.txt to all 5 manual script builders
  (auth-failure, graphql-errors, bot-only-truncation,
  discussions-truncated, no-ideas-category)
- Fix date fallback format: append T00:00:00Z to date_days_ago output
  so the JSON Schema format:date-time constraint is satisfied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compose-signals.bats): update call sites to 12-arg signature

All compose_signals invocations now pass last_successful_run as
the new arg 10, shifting schema_version to 11 and
truncation_warnings to 12. Also adds last_successful_run to the
required-fields assertion in the empty-inputs test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): address CodeRabbit and Copilot review comments

- collect-signals.sh: use WORKFLOW_FILE env var (default: feature-ideation.yml)
  so repos that rename their caller stub can override without a code change;
  capture gh run list stderr in a temp file and log it when the fallback is
  triggered so auth/network failures are distinguishable from first-run
- feature-ideation-reusable.yml: clarify propagation comment — changes reach
  @v1 stubs only after the v1 tag is bumped, not on every next run
- ci-standards.md: align Tier-1 table wording with the @v1 tag-bump model
- standards/workflows/feature-ideation.yml: reword sources_file comment to
  make clear users must uncomment AND change the path for non-default locations;
  show a non-default example path to reduce ambiguity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add self-test feature-ideation stub for dry-run validation

* fix: trailing newline + clean up stub

* fix: pin reusable workflow ref to commit SHA (SonarCloud)

* chore: remove temporary test stub (not for main)

* fix(reusable): guard against empty sources_file in Phase 2 prompt

If a caller passes sources_file: '' the prompt previously rendered a
bare 'Read: ' instruction. Now uses a GitHub Actions expression to
branch: non-empty value emits the Read instruction; empty/omitted
emits a clear fallback note directing Mary to open web search and log
a warning in the step summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): move sources_file expression to env var to respect line-length

The format() expression was 241 chars, over the 200-char yamllint limit.
Moving it to SOURCES_INSTRUCTION in the step env block (where the
expression is still valid) and referencing $SOURCES_INSTRUCTION in the
prompt string brings all lines under 200 chars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): resolve YAML syntax error in sources_file prompt guard

The format() expression with backtick literals inside a GHA expression
caused a YAML mapping-value syntax error at parse time. Replaced with
a plain env var SOURCES_FILE_PATH + shell-style conditional in the prompt
text — no GHA expressions inside the multiline prompt string, fully
YAML-safe and under the 200-char line limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(dotgithub): add feature-ideation caller stub for .github self-test

Adds the Feature Research & Ideation workflow to the .github repo itself,
making it a BMAD-enabled consumer of its own reusable pipeline.

Key configuration:
- project_context: org-level DevX/tooling repo (CI standards, reusable
  workflows, BMAD framework, agent security)
- sources_file: 'standards/feature-ideation-sources.md' — the template
  lives right here, so no copy needed
- dry_run defaults to false (use workflow_dispatch input to enable)
- actions: read permission for feed checkpoint

Note: uses: SHA points to current v1. After this PR merges, bump the
v1 tag to the new merge commit and update the SHA here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
don-petry added a commit that referenced this pull request Jun 8, 2026
)

* feat(feature-ideation): per-repo source list + feed checkpoint via last successful run

Source list (addresses all Copilot/CodeRabbit/don-petry review threads):
- Add standards/feature-ideation-sources.md as a starter template; each
  adopting repo copies it to .github/feature-ideation-sources.md and owns
  it independently (no cross-repo checkout).
- Add sources_file input to the reusable workflow (default:
  .github/feature-ideation-sources.md). Phase 2 prompt reads the repo-
  local file; falls back to open web search if absent.
- Fix three arXiv RSS feed URLs from http:// to https://.
- Update propagation wording in ci-standards.md to reflect per-repo
  ownership and v1 tag model.
- Pin caller stub reusable ref from mutable @v1 to commit SHA ae9709f # v1.
- Add actions: read to gather-signals permissions and caller stub template
  (required for gh run list in same repo).

Feed checkpoint (new — avoids re-reviewing same content every week):
- collect-signals.sh: query gh run list --status=success --limit=1 to
  resolve the previous successful run timestamp; fall back to 30 days ago
  on first run or after a long outage.
- compose-signals.sh: add last_successful_run as arg 10 (schema_version
  shifts to arg 11, truncation_warnings to arg 12).
- signals.schema.json: add last_successful_run field; bump schema version
  1.0.0 → 1.1.0 (SCHEMA_VERSION constant updated in lockstep per bats test).
- Test fixtures (populated, empty-repo, truncated): add last_successful_run
  and bump schema_version to 1.1.0.
- Phase 2 prompt: instruct Mary to filter feed entries to those published
  after last_successful_run; bypass checkpoint if >60 days old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(feature-ideation): validate ISO-8601 format for last_successful_run fallback

The gh stub used in bats tests returns raw fixture JSON without applying
--jq filters, so the captured last_successful_run value was a JSON array
instead of an ISO-8601 timestamp. Add a grep -qE '^[0-9]{4}-...' guard
that falls back to the 30-day default whenever the output is not a valid
date-time string, keeping all existing bats tests green without requiring
every test script to stub the new gh run list call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(collect-signals): align bats stub order with new gh run list call

The feed-checkpoint `gh run list` call added in the previous commit is
now the *first* gh invocation, so every manually-built stub script in
collect-signals.bats needs a corresponding first entry.

- Prepend run-list-last-success.txt to all 5 manual script builders
  (auth-failure, graphql-errors, bot-only-truncation,
  discussions-truncated, no-ideas-category)
- Fix date fallback format: append T00:00:00Z to date_days_ago output
  so the JSON Schema format:date-time constraint is satisfied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compose-signals.bats): update call sites to 12-arg signature

All compose_signals invocations now pass last_successful_run as
the new arg 10, shifting schema_version to 11 and
truncation_warnings to 12. Also adds last_successful_run to the
required-fields assertion in the empty-inputs test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): address CodeRabbit and Copilot review comments

- collect-signals.sh: use WORKFLOW_FILE env var (default: feature-ideation.yml)
  so repos that rename their caller stub can override without a code change;
  capture gh run list stderr in a temp file and log it when the fallback is
  triggered so auth/network failures are distinguishable from first-run
- feature-ideation-reusable.yml: clarify propagation comment — changes reach
  @v1 stubs only after the v1 tag is bumped, not on every next run
- ci-standards.md: align Tier-1 table wording with the @v1 tag-bump model
- standards/workflows/feature-ideation.yml: reword sources_file comment to
  make clear users must uncomment AND change the path for non-default locations;
  show a non-default example path to reduce ambiguity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add self-test feature-ideation stub for dry-run validation

* fix: trailing newline + clean up stub

* fix: pin reusable workflow ref to commit SHA (SonarCloud)

* chore: remove temporary test stub (not for main)

* fix(reusable): guard against empty sources_file in Phase 2 prompt

If a caller passes sources_file: '' the prompt previously rendered a
bare 'Read: ' instruction. Now uses a GitHub Actions expression to
branch: non-empty value emits the Read instruction; empty/omitted
emits a clear fallback note directing Mary to open web search and log
a warning in the step summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): move sources_file expression to env var to respect line-length

The format() expression was 241 chars, over the 200-char yamllint limit.
Moving it to SOURCES_INSTRUCTION in the step env block (where the
expression is still valid) and referencing $SOURCES_INSTRUCTION in the
prompt string brings all lines under 200 chars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): resolve YAML syntax error in sources_file prompt guard

The format() expression with backtick literals inside a GHA expression
caused a YAML mapping-value syntax error at parse time. Replaced with
a plain env var SOURCES_FILE_PATH + shell-style conditional in the prompt
text — no GHA expressions inside the multiline prompt string, fully
YAML-safe and under the 200-char line limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(dotgithub): add feature-ideation caller stub for .github self-test

Adds the Feature Research & Ideation workflow to the .github repo itself,
making it a BMAD-enabled consumer of its own reusable pipeline.

Key configuration:
- project_context: org-level DevX/tooling repo (CI standards, reusable
  workflows, BMAD framework, agent security)
- sources_file: 'standards/feature-ideation-sources.md' — the template
  lives right here, so no copy needed
- dry_run defaults to false (use workflow_dispatch input to enable)
- actions: read permission for feed checkpoint

Note: uses: SHA points to current v1. After this PR merges, bump the
v1 tag to the new merge commit and update the SHA here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
don-petry added a commit that referenced this pull request Jun 10, 2026
)

* feat(feature-ideation): per-repo source list + feed checkpoint via last successful run

Source list (addresses all Copilot/CodeRabbit/don-petry review threads):
- Add standards/feature-ideation-sources.md as a starter template; each
  adopting repo copies it to .github/feature-ideation-sources.md and owns
  it independently (no cross-repo checkout).
- Add sources_file input to the reusable workflow (default:
  .github/feature-ideation-sources.md). Phase 2 prompt reads the repo-
  local file; falls back to open web search if absent.
- Fix three arXiv RSS feed URLs from http:// to https://.
- Update propagation wording in ci-standards.md to reflect per-repo
  ownership and v1 tag model.
- Pin caller stub reusable ref from mutable @v1 to commit SHA ae9709f # v1.
- Add actions: read to gather-signals permissions and caller stub template
  (required for gh run list in same repo).

Feed checkpoint (new — avoids re-reviewing same content every week):
- collect-signals.sh: query gh run list --status=success --limit=1 to
  resolve the previous successful run timestamp; fall back to 30 days ago
  on first run or after a long outage.
- compose-signals.sh: add last_successful_run as arg 10 (schema_version
  shifts to arg 11, truncation_warnings to arg 12).
- signals.schema.json: add last_successful_run field; bump schema version
  1.0.0 → 1.1.0 (SCHEMA_VERSION constant updated in lockstep per bats test).
- Test fixtures (populated, empty-repo, truncated): add last_successful_run
  and bump schema_version to 1.1.0.
- Phase 2 prompt: instruct Mary to filter feed entries to those published
  after last_successful_run; bypass checkpoint if >60 days old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(feature-ideation): validate ISO-8601 format for last_successful_run fallback

The gh stub used in bats tests returns raw fixture JSON without applying
--jq filters, so the captured last_successful_run value was a JSON array
instead of an ISO-8601 timestamp. Add a grep -qE '^[0-9]{4}-...' guard
that falls back to the 30-day default whenever the output is not a valid
date-time string, keeping all existing bats tests green without requiring
every test script to stub the new gh run list call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(collect-signals): align bats stub order with new gh run list call

The feed-checkpoint `gh run list` call added in the previous commit is
now the *first* gh invocation, so every manually-built stub script in
collect-signals.bats needs a corresponding first entry.

- Prepend run-list-last-success.txt to all 5 manual script builders
  (auth-failure, graphql-errors, bot-only-truncation,
  discussions-truncated, no-ideas-category)
- Fix date fallback format: append T00:00:00Z to date_days_ago output
  so the JSON Schema format:date-time constraint is satisfied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compose-signals.bats): update call sites to 12-arg signature

All compose_signals invocations now pass last_successful_run as
the new arg 10, shifting schema_version to 11 and
truncation_warnings to 12. Also adds last_successful_run to the
required-fields assertion in the empty-inputs test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): address CodeRabbit and Copilot review comments

- collect-signals.sh: use WORKFLOW_FILE env var (default: feature-ideation.yml)
  so repos that rename their caller stub can override without a code change;
  capture gh run list stderr in a temp file and log it when the fallback is
  triggered so auth/network failures are distinguishable from first-run
- feature-ideation-reusable.yml: clarify propagation comment — changes reach
  @v1 stubs only after the v1 tag is bumped, not on every next run
- ci-standards.md: align Tier-1 table wording with the @v1 tag-bump model
- standards/workflows/feature-ideation.yml: reword sources_file comment to
  make clear users must uncomment AND change the path for non-default locations;
  show a non-default example path to reduce ambiguity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add self-test feature-ideation stub for dry-run validation

* fix: trailing newline + clean up stub

* fix: pin reusable workflow ref to commit SHA (SonarCloud)

* chore: remove temporary test stub (not for main)

* fix(reusable): guard against empty sources_file in Phase 2 prompt

If a caller passes sources_file: '' the prompt previously rendered a
bare 'Read: ' instruction. Now uses a GitHub Actions expression to
branch: non-empty value emits the Read instruction; empty/omitted
emits a clear fallback note directing Mary to open web search and log
a warning in the step summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): move sources_file expression to env var to respect line-length

The format() expression was 241 chars, over the 200-char yamllint limit.
Moving it to SOURCES_INSTRUCTION in the step env block (where the
expression is still valid) and referencing $SOURCES_INSTRUCTION in the
prompt string brings all lines under 200 chars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): resolve YAML syntax error in sources_file prompt guard

The format() expression with backtick literals inside a GHA expression
caused a YAML mapping-value syntax error at parse time. Replaced with
a plain env var SOURCES_FILE_PATH + shell-style conditional in the prompt
text — no GHA expressions inside the multiline prompt string, fully
YAML-safe and under the 200-char line limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(dotgithub): add feature-ideation caller stub for .github self-test

Adds the Feature Research & Ideation workflow to the .github repo itself,
making it a BMAD-enabled consumer of its own reusable pipeline.

Key configuration:
- project_context: org-level DevX/tooling repo (CI standards, reusable
  workflows, BMAD framework, agent security)
- sources_file: 'standards/feature-ideation-sources.md' — the template
  lives right here, so no copy needed
- dry_run defaults to false (use workflow_dispatch input to enable)
- actions: read permission for feed checkpoint

Note: uses: SHA points to current v1. After this PR merges, bump the
v1 tag to the new merge commit and update the SHA here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
don-petry added a commit that referenced this pull request Jun 11, 2026
)

* feat(feature-ideation): per-repo source list + feed checkpoint via last successful run

Source list (addresses all Copilot/CodeRabbit/don-petry review threads):
- Add standards/feature-ideation-sources.md as a starter template; each
  adopting repo copies it to .github/feature-ideation-sources.md and owns
  it independently (no cross-repo checkout).
- Add sources_file input to the reusable workflow (default:
  .github/feature-ideation-sources.md). Phase 2 prompt reads the repo-
  local file; falls back to open web search if absent.
- Fix three arXiv RSS feed URLs from http:// to https://.
- Update propagation wording in ci-standards.md to reflect per-repo
  ownership and v1 tag model.
- Pin caller stub reusable ref from mutable @v1 to commit SHA ae9709f # v1.
- Add actions: read to gather-signals permissions and caller stub template
  (required for gh run list in same repo).

Feed checkpoint (new — avoids re-reviewing same content every week):
- collect-signals.sh: query gh run list --status=success --limit=1 to
  resolve the previous successful run timestamp; fall back to 30 days ago
  on first run or after a long outage.
- compose-signals.sh: add last_successful_run as arg 10 (schema_version
  shifts to arg 11, truncation_warnings to arg 12).
- signals.schema.json: add last_successful_run field; bump schema version
  1.0.0 → 1.1.0 (SCHEMA_VERSION constant updated in lockstep per bats test).
- Test fixtures (populated, empty-repo, truncated): add last_successful_run
  and bump schema_version to 1.1.0.
- Phase 2 prompt: instruct Mary to filter feed entries to those published
  after last_successful_run; bypass checkpoint if >60 days old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(feature-ideation): validate ISO-8601 format for last_successful_run fallback

The gh stub used in bats tests returns raw fixture JSON without applying
--jq filters, so the captured last_successful_run value was a JSON array
instead of an ISO-8601 timestamp. Add a grep -qE '^[0-9]{4}-...' guard
that falls back to the 30-day default whenever the output is not a valid
date-time string, keeping all existing bats tests green without requiring
every test script to stub the new gh run list call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(collect-signals): align bats stub order with new gh run list call

The feed-checkpoint `gh run list` call added in the previous commit is
now the *first* gh invocation, so every manually-built stub script in
collect-signals.bats needs a corresponding first entry.

- Prepend run-list-last-success.txt to all 5 manual script builders
  (auth-failure, graphql-errors, bot-only-truncation,
  discussions-truncated, no-ideas-category)
- Fix date fallback format: append T00:00:00Z to date_days_ago output
  so the JSON Schema format:date-time constraint is satisfied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compose-signals.bats): update call sites to 12-arg signature

All compose_signals invocations now pass last_successful_run as
the new arg 10, shifting schema_version to 11 and
truncation_warnings to 12. Also adds last_successful_run to the
required-fields assertion in the empty-inputs test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): address CodeRabbit and Copilot review comments

- collect-signals.sh: use WORKFLOW_FILE env var (default: feature-ideation.yml)
  so repos that rename their caller stub can override without a code change;
  capture gh run list stderr in a temp file and log it when the fallback is
  triggered so auth/network failures are distinguishable from first-run
- feature-ideation-reusable.yml: clarify propagation comment — changes reach
  @v1 stubs only after the v1 tag is bumped, not on every next run
- ci-standards.md: align Tier-1 table wording with the @v1 tag-bump model
- standards/workflows/feature-ideation.yml: reword sources_file comment to
  make clear users must uncomment AND change the path for non-default locations;
  show a non-default example path to reduce ambiguity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add self-test feature-ideation stub for dry-run validation

* fix: trailing newline + clean up stub

* fix: pin reusable workflow ref to commit SHA (SonarCloud)

* chore: remove temporary test stub (not for main)

* fix(reusable): guard against empty sources_file in Phase 2 prompt

If a caller passes sources_file: '' the prompt previously rendered a
bare 'Read: ' instruction. Now uses a GitHub Actions expression to
branch: non-empty value emits the Read instruction; empty/omitted
emits a clear fallback note directing Mary to open web search and log
a warning in the step summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): move sources_file expression to env var to respect line-length

The format() expression was 241 chars, over the 200-char yamllint limit.
Moving it to SOURCES_INSTRUCTION in the step env block (where the
expression is still valid) and referencing $SOURCES_INSTRUCTION in the
prompt string brings all lines under 200 chars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): resolve YAML syntax error in sources_file prompt guard

The format() expression with backtick literals inside a GHA expression
caused a YAML mapping-value syntax error at parse time. Replaced with
a plain env var SOURCES_FILE_PATH + shell-style conditional in the prompt
text — no GHA expressions inside the multiline prompt string, fully
YAML-safe and under the 200-char line limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(dotgithub): add feature-ideation caller stub for .github self-test

Adds the Feature Research & Ideation workflow to the .github repo itself,
making it a BMAD-enabled consumer of its own reusable pipeline.

Key configuration:
- project_context: org-level DevX/tooling repo (CI standards, reusable
  workflows, BMAD framework, agent security)
- sources_file: 'standards/feature-ideation-sources.md' — the template
  lives right here, so no copy needed
- dry_run defaults to false (use workflow_dispatch input to enable)
- actions: read permission for feed checkpoint

Note: uses: SHA points to current v1. After this PR merges, bump the
v1 tag to the new merge commit and update the SHA here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
don-petry added a commit that referenced this pull request Jun 11, 2026
)

* feat(feature-ideation): per-repo source list + feed checkpoint via last successful run

Source list (addresses all Copilot/CodeRabbit/don-petry review threads):
- Add standards/feature-ideation-sources.md as a starter template; each
  adopting repo copies it to .github/feature-ideation-sources.md and owns
  it independently (no cross-repo checkout).
- Add sources_file input to the reusable workflow (default:
  .github/feature-ideation-sources.md). Phase 2 prompt reads the repo-
  local file; falls back to open web search if absent.
- Fix three arXiv RSS feed URLs from http:// to https://.
- Update propagation wording in ci-standards.md to reflect per-repo
  ownership and v1 tag model.
- Pin caller stub reusable ref from mutable @v1 to commit SHA ae9709f # v1.
- Add actions: read to gather-signals permissions and caller stub template
  (required for gh run list in same repo).

Feed checkpoint (new — avoids re-reviewing same content every week):
- collect-signals.sh: query gh run list --status=success --limit=1 to
  resolve the previous successful run timestamp; fall back to 30 days ago
  on first run or after a long outage.
- compose-signals.sh: add last_successful_run as arg 10 (schema_version
  shifts to arg 11, truncation_warnings to arg 12).
- signals.schema.json: add last_successful_run field; bump schema version
  1.0.0 → 1.1.0 (SCHEMA_VERSION constant updated in lockstep per bats test).
- Test fixtures (populated, empty-repo, truncated): add last_successful_run
  and bump schema_version to 1.1.0.
- Phase 2 prompt: instruct Mary to filter feed entries to those published
  after last_successful_run; bypass checkpoint if >60 days old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(feature-ideation): validate ISO-8601 format for last_successful_run fallback

The gh stub used in bats tests returns raw fixture JSON without applying
--jq filters, so the captured last_successful_run value was a JSON array
instead of an ISO-8601 timestamp. Add a grep -qE '^[0-9]{4}-...' guard
that falls back to the 30-day default whenever the output is not a valid
date-time string, keeping all existing bats tests green without requiring
every test script to stub the new gh run list call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(collect-signals): align bats stub order with new gh run list call

The feed-checkpoint `gh run list` call added in the previous commit is
now the *first* gh invocation, so every manually-built stub script in
collect-signals.bats needs a corresponding first entry.

- Prepend run-list-last-success.txt to all 5 manual script builders
  (auth-failure, graphql-errors, bot-only-truncation,
  discussions-truncated, no-ideas-category)
- Fix date fallback format: append T00:00:00Z to date_days_ago output
  so the JSON Schema format:date-time constraint is satisfied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compose-signals.bats): update call sites to 12-arg signature

All compose_signals invocations now pass last_successful_run as
the new arg 10, shifting schema_version to 11 and
truncation_warnings to 12. Also adds last_successful_run to the
required-fields assertion in the empty-inputs test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): address CodeRabbit and Copilot review comments

- collect-signals.sh: use WORKFLOW_FILE env var (default: feature-ideation.yml)
  so repos that rename their caller stub can override without a code change;
  capture gh run list stderr in a temp file and log it when the fallback is
  triggered so auth/network failures are distinguishable from first-run
- feature-ideation-reusable.yml: clarify propagation comment — changes reach
  @v1 stubs only after the v1 tag is bumped, not on every next run
- ci-standards.md: align Tier-1 table wording with the @v1 tag-bump model
- standards/workflows/feature-ideation.yml: reword sources_file comment to
  make clear users must uncomment AND change the path for non-default locations;
  show a non-default example path to reduce ambiguity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add self-test feature-ideation stub for dry-run validation

* fix: trailing newline + clean up stub

* fix: pin reusable workflow ref to commit SHA (SonarCloud)

* chore: remove temporary test stub (not for main)

* fix(reusable): guard against empty sources_file in Phase 2 prompt

If a caller passes sources_file: '' the prompt previously rendered a
bare 'Read: ' instruction. Now uses a GitHub Actions expression to
branch: non-empty value emits the Read instruction; empty/omitted
emits a clear fallback note directing Mary to open web search and log
a warning in the step summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): move sources_file expression to env var to respect line-length

The format() expression was 241 chars, over the 200-char yamllint limit.
Moving it to SOURCES_INSTRUCTION in the step env block (where the
expression is still valid) and referencing $SOURCES_INSTRUCTION in the
prompt string brings all lines under 200 chars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): resolve YAML syntax error in sources_file prompt guard

The format() expression with backtick literals inside a GHA expression
caused a YAML mapping-value syntax error at parse time. Replaced with
a plain env var SOURCES_FILE_PATH + shell-style conditional in the prompt
text — no GHA expressions inside the multiline prompt string, fully
YAML-safe and under the 200-char line limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(dotgithub): add feature-ideation caller stub for .github self-test

Adds the Feature Research & Ideation workflow to the .github repo itself,
making it a BMAD-enabled consumer of its own reusable pipeline.

Key configuration:
- project_context: org-level DevX/tooling repo (CI standards, reusable
  workflows, BMAD framework, agent security)
- sources_file: 'standards/feature-ideation-sources.md' — the template
  lives right here, so no copy needed
- dry_run defaults to false (use workflow_dispatch input to enable)
- actions: read permission for feed checkpoint

Note: uses: SHA points to current v1. After this PR merges, bump the
v1 tag to the new merge commit and update the SHA here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
don-petry added a commit that referenced this pull request Jun 11, 2026
)

* feat(feature-ideation): per-repo source list + feed checkpoint via last successful run

Source list (addresses all Copilot/CodeRabbit/don-petry review threads):
- Add standards/feature-ideation-sources.md as a starter template; each
  adopting repo copies it to .github/feature-ideation-sources.md and owns
  it independently (no cross-repo checkout).
- Add sources_file input to the reusable workflow (default:
  .github/feature-ideation-sources.md). Phase 2 prompt reads the repo-
  local file; falls back to open web search if absent.
- Fix three arXiv RSS feed URLs from http:// to https://.
- Update propagation wording in ci-standards.md to reflect per-repo
  ownership and v1 tag model.
- Pin caller stub reusable ref from mutable @v1 to commit SHA ae9709f # v1.
- Add actions: read to gather-signals permissions and caller stub template
  (required for gh run list in same repo).

Feed checkpoint (new — avoids re-reviewing same content every week):
- collect-signals.sh: query gh run list --status=success --limit=1 to
  resolve the previous successful run timestamp; fall back to 30 days ago
  on first run or after a long outage.
- compose-signals.sh: add last_successful_run as arg 10 (schema_version
  shifts to arg 11, truncation_warnings to arg 12).
- signals.schema.json: add last_successful_run field; bump schema version
  1.0.0 → 1.1.0 (SCHEMA_VERSION constant updated in lockstep per bats test).
- Test fixtures (populated, empty-repo, truncated): add last_successful_run
  and bump schema_version to 1.1.0.
- Phase 2 prompt: instruct Mary to filter feed entries to those published
  after last_successful_run; bypass checkpoint if >60 days old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(feature-ideation): validate ISO-8601 format for last_successful_run fallback

The gh stub used in bats tests returns raw fixture JSON without applying
--jq filters, so the captured last_successful_run value was a JSON array
instead of an ISO-8601 timestamp. Add a grep -qE '^[0-9]{4}-...' guard
that falls back to the 30-day default whenever the output is not a valid
date-time string, keeping all existing bats tests green without requiring
every test script to stub the new gh run list call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(collect-signals): align bats stub order with new gh run list call

The feed-checkpoint `gh run list` call added in the previous commit is
now the *first* gh invocation, so every manually-built stub script in
collect-signals.bats needs a corresponding first entry.

- Prepend run-list-last-success.txt to all 5 manual script builders
  (auth-failure, graphql-errors, bot-only-truncation,
  discussions-truncated, no-ideas-category)
- Fix date fallback format: append T00:00:00Z to date_days_ago output
  so the JSON Schema format:date-time constraint is satisfied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compose-signals.bats): update call sites to 12-arg signature

All compose_signals invocations now pass last_successful_run as
the new arg 10, shifting schema_version to 11 and
truncation_warnings to 12. Also adds last_successful_run to the
required-fields assertion in the empty-inputs test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): address CodeRabbit and Copilot review comments

- collect-signals.sh: use WORKFLOW_FILE env var (default: feature-ideation.yml)
  so repos that rename their caller stub can override without a code change;
  capture gh run list stderr in a temp file and log it when the fallback is
  triggered so auth/network failures are distinguishable from first-run
- feature-ideation-reusable.yml: clarify propagation comment — changes reach
  @v1 stubs only after the v1 tag is bumped, not on every next run
- ci-standards.md: align Tier-1 table wording with the @v1 tag-bump model
- standards/workflows/feature-ideation.yml: reword sources_file comment to
  make clear users must uncomment AND change the path for non-default locations;
  show a non-default example path to reduce ambiguity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add self-test feature-ideation stub for dry-run validation

* fix: trailing newline + clean up stub

* fix: pin reusable workflow ref to commit SHA (SonarCloud)

* chore: remove temporary test stub (not for main)

* fix(reusable): guard against empty sources_file in Phase 2 prompt

If a caller passes sources_file: '' the prompt previously rendered a
bare 'Read: ' instruction. Now uses a GitHub Actions expression to
branch: non-empty value emits the Read instruction; empty/omitted
emits a clear fallback note directing Mary to open web search and log
a warning in the step summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): move sources_file expression to env var to respect line-length

The format() expression was 241 chars, over the 200-char yamllint limit.
Moving it to SOURCES_INSTRUCTION in the step env block (where the
expression is still valid) and referencing $SOURCES_INSTRUCTION in the
prompt string brings all lines under 200 chars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): resolve YAML syntax error in sources_file prompt guard

The format() expression with backtick literals inside a GHA expression
caused a YAML mapping-value syntax error at parse time. Replaced with
a plain env var SOURCES_FILE_PATH + shell-style conditional in the prompt
text — no GHA expressions inside the multiline prompt string, fully
YAML-safe and under the 200-char line limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(dotgithub): add feature-ideation caller stub for .github self-test

Adds the Feature Research & Ideation workflow to the .github repo itself,
making it a BMAD-enabled consumer of its own reusable pipeline.

Key configuration:
- project_context: org-level DevX/tooling repo (CI standards, reusable
  workflows, BMAD framework, agent security)
- sources_file: 'standards/feature-ideation-sources.md' — the template
  lives right here, so no copy needed
- dry_run defaults to false (use workflow_dispatch input to enable)
- actions: read permission for feed checkpoint

Note: uses: SHA points to current v1. After this PR merges, bump the
v1 tag to the new merge commit and update the SHA here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
don-petry added a commit that referenced this pull request Jun 11, 2026
)

* feat(feature-ideation): per-repo source list + feed checkpoint via last successful run

Source list (addresses all Copilot/CodeRabbit/don-petry review threads):
- Add standards/feature-ideation-sources.md as a starter template; each
  adopting repo copies it to .github/feature-ideation-sources.md and owns
  it independently (no cross-repo checkout).
- Add sources_file input to the reusable workflow (default:
  .github/feature-ideation-sources.md). Phase 2 prompt reads the repo-
  local file; falls back to open web search if absent.
- Fix three arXiv RSS feed URLs from http:// to https://.
- Update propagation wording in ci-standards.md to reflect per-repo
  ownership and v1 tag model.
- Pin caller stub reusable ref from mutable @v1 to commit SHA ae9709f # v1.
- Add actions: read to gather-signals permissions and caller stub template
  (required for gh run list in same repo).

Feed checkpoint (new — avoids re-reviewing same content every week):
- collect-signals.sh: query gh run list --status=success --limit=1 to
  resolve the previous successful run timestamp; fall back to 30 days ago
  on first run or after a long outage.
- compose-signals.sh: add last_successful_run as arg 10 (schema_version
  shifts to arg 11, truncation_warnings to arg 12).
- signals.schema.json: add last_successful_run field; bump schema version
  1.0.0 → 1.1.0 (SCHEMA_VERSION constant updated in lockstep per bats test).
- Test fixtures (populated, empty-repo, truncated): add last_successful_run
  and bump schema_version to 1.1.0.
- Phase 2 prompt: instruct Mary to filter feed entries to those published
  after last_successful_run; bypass checkpoint if >60 days old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(feature-ideation): validate ISO-8601 format for last_successful_run fallback

The gh stub used in bats tests returns raw fixture JSON without applying
--jq filters, so the captured last_successful_run value was a JSON array
instead of an ISO-8601 timestamp. Add a grep -qE '^[0-9]{4}-...' guard
that falls back to the 30-day default whenever the output is not a valid
date-time string, keeping all existing bats tests green without requiring
every test script to stub the new gh run list call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(collect-signals): align bats stub order with new gh run list call

The feed-checkpoint `gh run list` call added in the previous commit is
now the *first* gh invocation, so every manually-built stub script in
collect-signals.bats needs a corresponding first entry.

- Prepend run-list-last-success.txt to all 5 manual script builders
  (auth-failure, graphql-errors, bot-only-truncation,
  discussions-truncated, no-ideas-category)
- Fix date fallback format: append T00:00:00Z to date_days_ago output
  so the JSON Schema format:date-time constraint is satisfied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compose-signals.bats): update call sites to 12-arg signature

All compose_signals invocations now pass last_successful_run as
the new arg 10, shifting schema_version to 11 and
truncation_warnings to 12. Also adds last_successful_run to the
required-fields assertion in the empty-inputs test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): address CodeRabbit and Copilot review comments

- collect-signals.sh: use WORKFLOW_FILE env var (default: feature-ideation.yml)
  so repos that rename their caller stub can override without a code change;
  capture gh run list stderr in a temp file and log it when the fallback is
  triggered so auth/network failures are distinguishable from first-run
- feature-ideation-reusable.yml: clarify propagation comment — changes reach
  @v1 stubs only after the v1 tag is bumped, not on every next run
- ci-standards.md: align Tier-1 table wording with the @v1 tag-bump model
- standards/workflows/feature-ideation.yml: reword sources_file comment to
  make clear users must uncomment AND change the path for non-default locations;
  show a non-default example path to reduce ambiguity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add self-test feature-ideation stub for dry-run validation

* fix: trailing newline + clean up stub

* fix: pin reusable workflow ref to commit SHA (SonarCloud)

* chore: remove temporary test stub (not for main)

* fix(reusable): guard against empty sources_file in Phase 2 prompt

If a caller passes sources_file: '' the prompt previously rendered a
bare 'Read: ' instruction. Now uses a GitHub Actions expression to
branch: non-empty value emits the Read instruction; empty/omitted
emits a clear fallback note directing Mary to open web search and log
a warning in the step summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): move sources_file expression to env var to respect line-length

The format() expression was 241 chars, over the 200-char yamllint limit.
Moving it to SOURCES_INSTRUCTION in the step env block (where the
expression is still valid) and referencing $SOURCES_INSTRUCTION in the
prompt string brings all lines under 200 chars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): resolve YAML syntax error in sources_file prompt guard

The format() expression with backtick literals inside a GHA expression
caused a YAML mapping-value syntax error at parse time. Replaced with
a plain env var SOURCES_FILE_PATH + shell-style conditional in the prompt
text — no GHA expressions inside the multiline prompt string, fully
YAML-safe and under the 200-char line limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(dotgithub): add feature-ideation caller stub for .github self-test

Adds the Feature Research & Ideation workflow to the .github repo itself,
making it a BMAD-enabled consumer of its own reusable pipeline.

Key configuration:
- project_context: org-level DevX/tooling repo (CI standards, reusable
  workflows, BMAD framework, agent security)
- sources_file: 'standards/feature-ideation-sources.md' — the template
  lives right here, so no copy needed
- dry_run defaults to false (use workflow_dispatch input to enable)
- actions: read permission for feed checkpoint

Note: uses: SHA points to current v1. After this PR merges, bump the
v1 tag to the new merge commit and update the SHA here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
don-petry added a commit that referenced this pull request Jun 11, 2026
)

* feat(feature-ideation): per-repo source list + feed checkpoint via last successful run

Source list (addresses all Copilot/CodeRabbit/don-petry review threads):
- Add standards/feature-ideation-sources.md as a starter template; each
  adopting repo copies it to .github/feature-ideation-sources.md and owns
  it independently (no cross-repo checkout).
- Add sources_file input to the reusable workflow (default:
  .github/feature-ideation-sources.md). Phase 2 prompt reads the repo-
  local file; falls back to open web search if absent.
- Fix three arXiv RSS feed URLs from http:// to https://.
- Update propagation wording in ci-standards.md to reflect per-repo
  ownership and v1 tag model.
- Pin caller stub reusable ref from mutable @v1 to commit SHA ae9709f # v1.
- Add actions: read to gather-signals permissions and caller stub template
  (required for gh run list in same repo).

Feed checkpoint (new — avoids re-reviewing same content every week):
- collect-signals.sh: query gh run list --status=success --limit=1 to
  resolve the previous successful run timestamp; fall back to 30 days ago
  on first run or after a long outage.
- compose-signals.sh: add last_successful_run as arg 10 (schema_version
  shifts to arg 11, truncation_warnings to arg 12).
- signals.schema.json: add last_successful_run field; bump schema version
  1.0.0 → 1.1.0 (SCHEMA_VERSION constant updated in lockstep per bats test).
- Test fixtures (populated, empty-repo, truncated): add last_successful_run
  and bump schema_version to 1.1.0.
- Phase 2 prompt: instruct Mary to filter feed entries to those published
  after last_successful_run; bypass checkpoint if >60 days old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(feature-ideation): validate ISO-8601 format for last_successful_run fallback

The gh stub used in bats tests returns raw fixture JSON without applying
--jq filters, so the captured last_successful_run value was a JSON array
instead of an ISO-8601 timestamp. Add a grep -qE '^[0-9]{4}-...' guard
that falls back to the 30-day default whenever the output is not a valid
date-time string, keeping all existing bats tests green without requiring
every test script to stub the new gh run list call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(collect-signals): align bats stub order with new gh run list call

The feed-checkpoint `gh run list` call added in the previous commit is
now the *first* gh invocation, so every manually-built stub script in
collect-signals.bats needs a corresponding first entry.

- Prepend run-list-last-success.txt to all 5 manual script builders
  (auth-failure, graphql-errors, bot-only-truncation,
  discussions-truncated, no-ideas-category)
- Fix date fallback format: append T00:00:00Z to date_days_ago output
  so the JSON Schema format:date-time constraint is satisfied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compose-signals.bats): update call sites to 12-arg signature

All compose_signals invocations now pass last_successful_run as
the new arg 10, shifting schema_version to 11 and
truncation_warnings to 12. Also adds last_successful_run to the
required-fields assertion in the empty-inputs test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): address CodeRabbit and Copilot review comments

- collect-signals.sh: use WORKFLOW_FILE env var (default: feature-ideation.yml)
  so repos that rename their caller stub can override without a code change;
  capture gh run list stderr in a temp file and log it when the fallback is
  triggered so auth/network failures are distinguishable from first-run
- feature-ideation-reusable.yml: clarify propagation comment — changes reach
  @v1 stubs only after the v1 tag is bumped, not on every next run
- ci-standards.md: align Tier-1 table wording with the @v1 tag-bump model
- standards/workflows/feature-ideation.yml: reword sources_file comment to
  make clear users must uncomment AND change the path for non-default locations;
  show a non-default example path to reduce ambiguity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add self-test feature-ideation stub for dry-run validation

* fix: trailing newline + clean up stub

* fix: pin reusable workflow ref to commit SHA (SonarCloud)

* chore: remove temporary test stub (not for main)

* fix(reusable): guard against empty sources_file in Phase 2 prompt

If a caller passes sources_file: '' the prompt previously rendered a
bare 'Read: ' instruction. Now uses a GitHub Actions expression to
branch: non-empty value emits the Read instruction; empty/omitted
emits a clear fallback note directing Mary to open web search and log
a warning in the step summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): move sources_file expression to env var to respect line-length

The format() expression was 241 chars, over the 200-char yamllint limit.
Moving it to SOURCES_INSTRUCTION in the step env block (where the
expression is still valid) and referencing $SOURCES_INSTRUCTION in the
prompt string brings all lines under 200 chars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): resolve YAML syntax error in sources_file prompt guard

The format() expression with backtick literals inside a GHA expression
caused a YAML mapping-value syntax error at parse time. Replaced with
a plain env var SOURCES_FILE_PATH + shell-style conditional in the prompt
text — no GHA expressions inside the multiline prompt string, fully
YAML-safe and under the 200-char line limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(dotgithub): add feature-ideation caller stub for .github self-test

Adds the Feature Research & Ideation workflow to the .github repo itself,
making it a BMAD-enabled consumer of its own reusable pipeline.

Key configuration:
- project_context: org-level DevX/tooling repo (CI standards, reusable
  workflows, BMAD framework, agent security)
- sources_file: 'standards/feature-ideation-sources.md' — the template
  lives right here, so no copy needed
- dry_run defaults to false (use workflow_dispatch input to enable)
- actions: read permission for feed checkpoint

Note: uses: SHA points to current v1. After this PR merges, bump the
v1 tag to the new merge commit and update the SHA here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
don-petry added a commit that referenced this pull request Jun 11, 2026
)

* feat(feature-ideation): per-repo source list + feed checkpoint via last successful run

Source list (addresses all Copilot/CodeRabbit/don-petry review threads):
- Add standards/feature-ideation-sources.md as a starter template; each
  adopting repo copies it to .github/feature-ideation-sources.md and owns
  it independently (no cross-repo checkout).
- Add sources_file input to the reusable workflow (default:
  .github/feature-ideation-sources.md). Phase 2 prompt reads the repo-
  local file; falls back to open web search if absent.
- Fix three arXiv RSS feed URLs from http:// to https://.
- Update propagation wording in ci-standards.md to reflect per-repo
  ownership and v1 tag model.
- Pin caller stub reusable ref from mutable @v1 to commit SHA ae9709f # v1.
- Add actions: read to gather-signals permissions and caller stub template
  (required for gh run list in same repo).

Feed checkpoint (new — avoids re-reviewing same content every week):
- collect-signals.sh: query gh run list --status=success --limit=1 to
  resolve the previous successful run timestamp; fall back to 30 days ago
  on first run or after a long outage.
- compose-signals.sh: add last_successful_run as arg 10 (schema_version
  shifts to arg 11, truncation_warnings to arg 12).
- signals.schema.json: add last_successful_run field; bump schema version
  1.0.0 → 1.1.0 (SCHEMA_VERSION constant updated in lockstep per bats test).
- Test fixtures (populated, empty-repo, truncated): add last_successful_run
  and bump schema_version to 1.1.0.
- Phase 2 prompt: instruct Mary to filter feed entries to those published
  after last_successful_run; bypass checkpoint if >60 days old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(feature-ideation): validate ISO-8601 format for last_successful_run fallback

The gh stub used in bats tests returns raw fixture JSON without applying
--jq filters, so the captured last_successful_run value was a JSON array
instead of an ISO-8601 timestamp. Add a grep -qE '^[0-9]{4}-...' guard
that falls back to the 30-day default whenever the output is not a valid
date-time string, keeping all existing bats tests green without requiring
every test script to stub the new gh run list call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(collect-signals): align bats stub order with new gh run list call

The feed-checkpoint `gh run list` call added in the previous commit is
now the *first* gh invocation, so every manually-built stub script in
collect-signals.bats needs a corresponding first entry.

- Prepend run-list-last-success.txt to all 5 manual script builders
  (auth-failure, graphql-errors, bot-only-truncation,
  discussions-truncated, no-ideas-category)
- Fix date fallback format: append T00:00:00Z to date_days_ago output
  so the JSON Schema format:date-time constraint is satisfied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compose-signals.bats): update call sites to 12-arg signature

All compose_signals invocations now pass last_successful_run as
the new arg 10, shifting schema_version to 11 and
truncation_warnings to 12. Also adds last_successful_run to the
required-fields assertion in the empty-inputs test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): address CodeRabbit and Copilot review comments

- collect-signals.sh: use WORKFLOW_FILE env var (default: feature-ideation.yml)
  so repos that rename their caller stub can override without a code change;
  capture gh run list stderr in a temp file and log it when the fallback is
  triggered so auth/network failures are distinguishable from first-run
- feature-ideation-reusable.yml: clarify propagation comment — changes reach
  @v1 stubs only after the v1 tag is bumped, not on every next run
- ci-standards.md: align Tier-1 table wording with the @v1 tag-bump model
- standards/workflows/feature-ideation.yml: reword sources_file comment to
  make clear users must uncomment AND change the path for non-default locations;
  show a non-default example path to reduce ambiguity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add self-test feature-ideation stub for dry-run validation

* fix: trailing newline + clean up stub

* fix: pin reusable workflow ref to commit SHA (SonarCloud)

* chore: remove temporary test stub (not for main)

* fix(reusable): guard against empty sources_file in Phase 2 prompt

If a caller passes sources_file: '' the prompt previously rendered a
bare 'Read: ' instruction. Now uses a GitHub Actions expression to
branch: non-empty value emits the Read instruction; empty/omitted
emits a clear fallback note directing Mary to open web search and log
a warning in the step summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): move sources_file expression to env var to respect line-length

The format() expression was 241 chars, over the 200-char yamllint limit.
Moving it to SOURCES_INSTRUCTION in the step env block (where the
expression is still valid) and referencing $SOURCES_INSTRUCTION in the
prompt string brings all lines under 200 chars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): resolve YAML syntax error in sources_file prompt guard

The format() expression with backtick literals inside a GHA expression
caused a YAML mapping-value syntax error at parse time. Replaced with
a plain env var SOURCES_FILE_PATH + shell-style conditional in the prompt
text — no GHA expressions inside the multiline prompt string, fully
YAML-safe and under the 200-char line limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(dotgithub): add feature-ideation caller stub for .github self-test

Adds the Feature Research & Ideation workflow to the .github repo itself,
making it a BMAD-enabled consumer of its own reusable pipeline.

Key configuration:
- project_context: org-level DevX/tooling repo (CI standards, reusable
  workflows, BMAD framework, agent security)
- sources_file: 'standards/feature-ideation-sources.md' — the template
  lives right here, so no copy needed
- dry_run defaults to false (use workflow_dispatch input to enable)
- actions: read permission for feed checkpoint

Note: uses: SHA points to current v1. After this PR merges, bump the
v1 tag to the new merge commit and update the SHA here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
don-petry added a commit that referenced this pull request Jun 11, 2026
)

* feat(feature-ideation): per-repo source list + feed checkpoint via last successful run

Source list (addresses all Copilot/CodeRabbit/don-petry review threads):
- Add standards/feature-ideation-sources.md as a starter template; each
  adopting repo copies it to .github/feature-ideation-sources.md and owns
  it independently (no cross-repo checkout).
- Add sources_file input to the reusable workflow (default:
  .github/feature-ideation-sources.md). Phase 2 prompt reads the repo-
  local file; falls back to open web search if absent.
- Fix three arXiv RSS feed URLs from http:// to https://.
- Update propagation wording in ci-standards.md to reflect per-repo
  ownership and v1 tag model.
- Pin caller stub reusable ref from mutable @v1 to commit SHA ae9709f # v1.
- Add actions: read to gather-signals permissions and caller stub template
  (required for gh run list in same repo).

Feed checkpoint (new — avoids re-reviewing same content every week):
- collect-signals.sh: query gh run list --status=success --limit=1 to
  resolve the previous successful run timestamp; fall back to 30 days ago
  on first run or after a long outage.
- compose-signals.sh: add last_successful_run as arg 10 (schema_version
  shifts to arg 11, truncation_warnings to arg 12).
- signals.schema.json: add last_successful_run field; bump schema version
  1.0.0 → 1.1.0 (SCHEMA_VERSION constant updated in lockstep per bats test).
- Test fixtures (populated, empty-repo, truncated): add last_successful_run
  and bump schema_version to 1.1.0.
- Phase 2 prompt: instruct Mary to filter feed entries to those published
  after last_successful_run; bypass checkpoint if >60 days old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(feature-ideation): validate ISO-8601 format for last_successful_run fallback

The gh stub used in bats tests returns raw fixture JSON without applying
--jq filters, so the captured last_successful_run value was a JSON array
instead of an ISO-8601 timestamp. Add a grep -qE '^[0-9]{4}-...' guard
that falls back to the 30-day default whenever the output is not a valid
date-time string, keeping all existing bats tests green without requiring
every test script to stub the new gh run list call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(collect-signals): align bats stub order with new gh run list call

The feed-checkpoint `gh run list` call added in the previous commit is
now the *first* gh invocation, so every manually-built stub script in
collect-signals.bats needs a corresponding first entry.

- Prepend run-list-last-success.txt to all 5 manual script builders
  (auth-failure, graphql-errors, bot-only-truncation,
  discussions-truncated, no-ideas-category)
- Fix date fallback format: append T00:00:00Z to date_days_ago output
  so the JSON Schema format:date-time constraint is satisfied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compose-signals.bats): update call sites to 12-arg signature

All compose_signals invocations now pass last_successful_run as
the new arg 10, shifting schema_version to 11 and
truncation_warnings to 12. Also adds last_successful_run to the
required-fields assertion in the empty-inputs test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): address CodeRabbit and Copilot review comments

- collect-signals.sh: use WORKFLOW_FILE env var (default: feature-ideation.yml)
  so repos that rename their caller stub can override without a code change;
  capture gh run list stderr in a temp file and log it when the fallback is
  triggered so auth/network failures are distinguishable from first-run
- feature-ideation-reusable.yml: clarify propagation comment — changes reach
  @v1 stubs only after the v1 tag is bumped, not on every next run
- ci-standards.md: align Tier-1 table wording with the @v1 tag-bump model
- standards/workflows/feature-ideation.yml: reword sources_file comment to
  make clear users must uncomment AND change the path for non-default locations;
  show a non-default example path to reduce ambiguity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add self-test feature-ideation stub for dry-run validation

* fix: trailing newline + clean up stub

* fix: pin reusable workflow ref to commit SHA (SonarCloud)

* chore: remove temporary test stub (not for main)

* fix(reusable): guard against empty sources_file in Phase 2 prompt

If a caller passes sources_file: '' the prompt previously rendered a
bare 'Read: ' instruction. Now uses a GitHub Actions expression to
branch: non-empty value emits the Read instruction; empty/omitted
emits a clear fallback note directing Mary to open web search and log
a warning in the step summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): move sources_file expression to env var to respect line-length

The format() expression was 241 chars, over the 200-char yamllint limit.
Moving it to SOURCES_INSTRUCTION in the step env block (where the
expression is still valid) and referencing $SOURCES_INSTRUCTION in the
prompt string brings all lines under 200 chars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): resolve YAML syntax error in sources_file prompt guard

The format() expression with backtick literals inside a GHA expression
caused a YAML mapping-value syntax error at parse time. Replaced with
a plain env var SOURCES_FILE_PATH + shell-style conditional in the prompt
text — no GHA expressions inside the multiline prompt string, fully
YAML-safe and under the 200-char line limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(dotgithub): add feature-ideation caller stub for .github self-test

Adds the Feature Research & Ideation workflow to the .github repo itself,
making it a BMAD-enabled consumer of its own reusable pipeline.

Key configuration:
- project_context: org-level DevX/tooling repo (CI standards, reusable
  workflows, BMAD framework, agent security)
- sources_file: 'standards/feature-ideation-sources.md' — the template
  lives right here, so no copy needed
- dry_run defaults to false (use workflow_dispatch input to enable)
- actions: read permission for feed checkpoint

Note: uses: SHA points to current v1. After this PR merges, bump the
v1 tag to the new merge commit and update the SHA here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
don-petry added a commit that referenced this pull request Jun 11, 2026
)

* feat(feature-ideation): per-repo source list + feed checkpoint via last successful run

Source list (addresses all Copilot/CodeRabbit/don-petry review threads):
- Add standards/feature-ideation-sources.md as a starter template; each
  adopting repo copies it to .github/feature-ideation-sources.md and owns
  it independently (no cross-repo checkout).
- Add sources_file input to the reusable workflow (default:
  .github/feature-ideation-sources.md). Phase 2 prompt reads the repo-
  local file; falls back to open web search if absent.
- Fix three arXiv RSS feed URLs from http:// to https://.
- Update propagation wording in ci-standards.md to reflect per-repo
  ownership and v1 tag model.
- Pin caller stub reusable ref from mutable @v1 to commit SHA ae9709f # v1.
- Add actions: read to gather-signals permissions and caller stub template
  (required for gh run list in same repo).

Feed checkpoint (new — avoids re-reviewing same content every week):
- collect-signals.sh: query gh run list --status=success --limit=1 to
  resolve the previous successful run timestamp; fall back to 30 days ago
  on first run or after a long outage.
- compose-signals.sh: add last_successful_run as arg 10 (schema_version
  shifts to arg 11, truncation_warnings to arg 12).
- signals.schema.json: add last_successful_run field; bump schema version
  1.0.0 → 1.1.0 (SCHEMA_VERSION constant updated in lockstep per bats test).
- Test fixtures (populated, empty-repo, truncated): add last_successful_run
  and bump schema_version to 1.1.0.
- Phase 2 prompt: instruct Mary to filter feed entries to those published
  after last_successful_run; bypass checkpoint if >60 days old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(feature-ideation): validate ISO-8601 format for last_successful_run fallback

The gh stub used in bats tests returns raw fixture JSON without applying
--jq filters, so the captured last_successful_run value was a JSON array
instead of an ISO-8601 timestamp. Add a grep -qE '^[0-9]{4}-...' guard
that falls back to the 30-day default whenever the output is not a valid
date-time string, keeping all existing bats tests green without requiring
every test script to stub the new gh run list call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(collect-signals): align bats stub order with new gh run list call

The feed-checkpoint `gh run list` call added in the previous commit is
now the *first* gh invocation, so every manually-built stub script in
collect-signals.bats needs a corresponding first entry.

- Prepend run-list-last-success.txt to all 5 manual script builders
  (auth-failure, graphql-errors, bot-only-truncation,
  discussions-truncated, no-ideas-category)
- Fix date fallback format: append T00:00:00Z to date_days_ago output
  so the JSON Schema format:date-time constraint is satisfied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compose-signals.bats): update call sites to 12-arg signature

All compose_signals invocations now pass last_successful_run as
the new arg 10, shifting schema_version to 11 and
truncation_warnings to 12. Also adds last_successful_run to the
required-fields assertion in the empty-inputs test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): address CodeRabbit and Copilot review comments

- collect-signals.sh: use WORKFLOW_FILE env var (default: feature-ideation.yml)
  so repos that rename their caller stub can override without a code change;
  capture gh run list stderr in a temp file and log it when the fallback is
  triggered so auth/network failures are distinguishable from first-run
- feature-ideation-reusable.yml: clarify propagation comment — changes reach
  @v1 stubs only after the v1 tag is bumped, not on every next run
- ci-standards.md: align Tier-1 table wording with the @v1 tag-bump model
- standards/workflows/feature-ideation.yml: reword sources_file comment to
  make clear users must uncomment AND change the path for non-default locations;
  show a non-default example path to reduce ambiguity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add self-test feature-ideation stub for dry-run validation

* fix: trailing newline + clean up stub

* fix: pin reusable workflow ref to commit SHA (SonarCloud)

* chore: remove temporary test stub (not for main)

* fix(reusable): guard against empty sources_file in Phase 2 prompt

If a caller passes sources_file: '' the prompt previously rendered a
bare 'Read: ' instruction. Now uses a GitHub Actions expression to
branch: non-empty value emits the Read instruction; empty/omitted
emits a clear fallback note directing Mary to open web search and log
a warning in the step summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): move sources_file expression to env var to respect line-length

The format() expression was 241 chars, over the 200-char yamllint limit.
Moving it to SOURCES_INSTRUCTION in the step env block (where the
expression is still valid) and referencing $SOURCES_INSTRUCTION in the
prompt string brings all lines under 200 chars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): resolve YAML syntax error in sources_file prompt guard

The format() expression with backtick literals inside a GHA expression
caused a YAML mapping-value syntax error at parse time. Replaced with
a plain env var SOURCES_FILE_PATH + shell-style conditional in the prompt
text — no GHA expressions inside the multiline prompt string, fully
YAML-safe and under the 200-char line limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(dotgithub): add feature-ideation caller stub for .github self-test

Adds the Feature Research & Ideation workflow to the .github repo itself,
making it a BMAD-enabled consumer of its own reusable pipeline.

Key configuration:
- project_context: org-level DevX/tooling repo (CI standards, reusable
  workflows, BMAD framework, agent security)
- sources_file: 'standards/feature-ideation-sources.md' — the template
  lives right here, so no copy needed
- dry_run defaults to false (use workflow_dispatch input to enable)
- actions: read permission for feed checkpoint

Note: uses: SHA points to current v1. After this PR merges, bump the
v1 tag to the new merge commit and update the SHA here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
don-petry added a commit that referenced this pull request Jun 11, 2026
)

* feat(feature-ideation): per-repo source list + feed checkpoint via last successful run

Source list (addresses all Copilot/CodeRabbit/don-petry review threads):
- Add standards/feature-ideation-sources.md as a starter template; each
  adopting repo copies it to .github/feature-ideation-sources.md and owns
  it independently (no cross-repo checkout).
- Add sources_file input to the reusable workflow (default:
  .github/feature-ideation-sources.md). Phase 2 prompt reads the repo-
  local file; falls back to open web search if absent.
- Fix three arXiv RSS feed URLs from http:// to https://.
- Update propagation wording in ci-standards.md to reflect per-repo
  ownership and v1 tag model.
- Pin caller stub reusable ref from mutable @v1 to commit SHA ae9709f # v1.
- Add actions: read to gather-signals permissions and caller stub template
  (required for gh run list in same repo).

Feed checkpoint (new — avoids re-reviewing same content every week):
- collect-signals.sh: query gh run list --status=success --limit=1 to
  resolve the previous successful run timestamp; fall back to 30 days ago
  on first run or after a long outage.
- compose-signals.sh: add last_successful_run as arg 10 (schema_version
  shifts to arg 11, truncation_warnings to arg 12).
- signals.schema.json: add last_successful_run field; bump schema version
  1.0.0 → 1.1.0 (SCHEMA_VERSION constant updated in lockstep per bats test).
- Test fixtures (populated, empty-repo, truncated): add last_successful_run
  and bump schema_version to 1.1.0.
- Phase 2 prompt: instruct Mary to filter feed entries to those published
  after last_successful_run; bypass checkpoint if >60 days old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(feature-ideation): validate ISO-8601 format for last_successful_run fallback

The gh stub used in bats tests returns raw fixture JSON without applying
--jq filters, so the captured last_successful_run value was a JSON array
instead of an ISO-8601 timestamp. Add a grep -qE '^[0-9]{4}-...' guard
that falls back to the 30-day default whenever the output is not a valid
date-time string, keeping all existing bats tests green without requiring
every test script to stub the new gh run list call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(collect-signals): align bats stub order with new gh run list call

The feed-checkpoint `gh run list` call added in the previous commit is
now the *first* gh invocation, so every manually-built stub script in
collect-signals.bats needs a corresponding first entry.

- Prepend run-list-last-success.txt to all 5 manual script builders
  (auth-failure, graphql-errors, bot-only-truncation,
  discussions-truncated, no-ideas-category)
- Fix date fallback format: append T00:00:00Z to date_days_ago output
  so the JSON Schema format:date-time constraint is satisfied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compose-signals.bats): update call sites to 12-arg signature

All compose_signals invocations now pass last_successful_run as
the new arg 10, shifting schema_version to 11 and
truncation_warnings to 12. Also adds last_successful_run to the
required-fields assertion in the empty-inputs test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): address CodeRabbit and Copilot review comments

- collect-signals.sh: use WORKFLOW_FILE env var (default: feature-ideation.yml)
  so repos that rename their caller stub can override without a code change;
  capture gh run list stderr in a temp file and log it when the fallback is
  triggered so auth/network failures are distinguishable from first-run
- feature-ideation-reusable.yml: clarify propagation comment — changes reach
  @v1 stubs only after the v1 tag is bumped, not on every next run
- ci-standards.md: align Tier-1 table wording with the @v1 tag-bump model
- standards/workflows/feature-ideation.yml: reword sources_file comment to
  make clear users must uncomment AND change the path for non-default locations;
  show a non-default example path to reduce ambiguity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add self-test feature-ideation stub for dry-run validation

* fix: trailing newline + clean up stub

* fix: pin reusable workflow ref to commit SHA (SonarCloud)

* chore: remove temporary test stub (not for main)

* fix(reusable): guard against empty sources_file in Phase 2 prompt

If a caller passes sources_file: '' the prompt previously rendered a
bare 'Read: ' instruction. Now uses a GitHub Actions expression to
branch: non-empty value emits the Read instruction; empty/omitted
emits a clear fallback note directing Mary to open web search and log
a warning in the step summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): move sources_file expression to env var to respect line-length

The format() expression was 241 chars, over the 200-char yamllint limit.
Moving it to SOURCES_INSTRUCTION in the step env block (where the
expression is still valid) and referencing $SOURCES_INSTRUCTION in the
prompt string brings all lines under 200 chars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): resolve YAML syntax error in sources_file prompt guard

The format() expression with backtick literals inside a GHA expression
caused a YAML mapping-value syntax error at parse time. Replaced with
a plain env var SOURCES_FILE_PATH + shell-style conditional in the prompt
text — no GHA expressions inside the multiline prompt string, fully
YAML-safe and under the 200-char line limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(dotgithub): add feature-ideation caller stub for .github self-test

Adds the Feature Research & Ideation workflow to the .github repo itself,
making it a BMAD-enabled consumer of its own reusable pipeline.

Key configuration:
- project_context: org-level DevX/tooling repo (CI standards, reusable
  workflows, BMAD framework, agent security)
- sources_file: 'standards/feature-ideation-sources.md' — the template
  lives right here, so no copy needed
- dry_run defaults to false (use workflow_dispatch input to enable)
- actions: read permission for feed checkpoint

Note: uses: SHA points to current v1. After this PR merges, bump the
v1 tag to the new merge commit and update the SHA here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
don-petry added a commit that referenced this pull request Jun 11, 2026
* Add multi-agent isolation strategy using git worktrees (#2)

* Add multi-agent isolation strategy using git worktrees

Define org-wide rules for running multiple AI agents concurrently
without conflicts: one worktree per agent, no overlapping file
ownership, tool-specific setup for Claude Code/Copilot/Codex/Cursor,
naming conventions, cleanup, and a pre-launch coordination checklist.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Address review comments: overlap detection, markdown fixes, branch clarity

- Add "Detecting File Overlap" subsection per CodeRabbit suggestion
- Reword origin/HEAD to reference default branch explicitly (Copilot)
- Qualify "name flows into branch" for manual worktrees (Copilot)
- Quote isolation: "worktree" consistently in YAML example (Copilot)
- Add git branch -D fallback for squash/rebase merges (Copilot)
- Fix markdown blank lines and language specifiers (CodeRabbit)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add weekly compliance audit workflow (#12)

* feat: add weekly compliance audit workflow

Adds automated weekly audit that checks all petry-projects repos
against org standards (CI, Dependabot, settings, labels, rulesets)
and creates/updates/closes issues for each finding.

- Deterministic shell script for reliable, repeatable checks
- Claude Code Action job for standards improvement research
- Issues auto-assigned to Claude for remediation
- Summary notification for org owners
- Idempotent: updates existing issues, closes resolved ones

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address review findings in compliance audit

- Add retry error logging to gh_api helper
- Fix pnpm detection when package.json absent
- Fix empty ecosystem array display
- Replace heredoc with direct assignment for issue body
- Add jq error safety in close_resolved_issues
- Increase repo list limit to 500 with empty check
- Use process substitution instead of pipe subshell
- Add concurrency group and timeout to workflow
- Add timeout-minutes to audit job

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address CodeRabbit and Copilot review comments

- Handle single-job workflows with job-level permissions
- Add has_issues to required settings checks
- Soften CODEOWNERS wording (SHOULD not MUST per standards)
- Remove misleading issues:write from audit job permissions
- Rename repo_count to repos_with_findings for clarity

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: do not auto-close previous summary issues

Per feedback, only humans should close summary/notification
issues. Changed Claude prompt to explicitly not close them.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: run compliance audit every Friday at noon UTC

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add full CI pipeline for .github repo (#15)

* feat: add full CI pipeline for .github repo

Adds all 6 required workflows per ci-standards.md:
- ci.yml: markdownlint, yamllint, actionlint, shellcheck, AgentShield
- codeql.yml: actions language analysis
- sonarcloud.yml: code quality scanning
- claude.yml: AI-assisted PR review
- dependabot-automerge.yml: auto-merge eligible PRs
- dependency-audit.yml: vulnerability scanning

Also adds:
- .github/dependabot.yml (github-actions ecosystem)
- .markdownlint-cli2.yaml (config for standards docs)
- sonar-project.properties

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: correct markdownlint SHA, use npx for AgentShield, remove duplicate CodeQL

- Fix markdownlint-cli2-action SHA to v9.0.0 (v20 doesn't exist)
- Use npx ecc-agentshield CLI instead of broken GitHub Action
- Remove codeql.yml — repo already has default CodeQL setup enabled

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: relax markdownlint rules, pin actionlint download

- Disable line-length, duplicate-heading, blanks-around-lists,
  bare-urls rules — existing docs have many violations; fix
  incrementally as separate PRs
- Replace curl|bash with pinned version download for actionlint
  (fixes SonarCloud security hotspot)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: break long line in org-scorecard.yml for yamllint

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: make actionlint fail on errors, guard shellcheck glob

- Remove || true from actionlint on our own workflows (fail properly)
- Keep || true only for template workflows (expected placeholder issues)
- Guard shellcheck glob against missing scripts/ directory

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: ignore shellcheck style hints in actionlint

SC2129 (use grouped redirects) is a style suggestion, not a bug.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: add SHA256 checksum verification for curl downloads

Addresses SonarCloud security hotspots by verifying checksums
on all binary downloads:
- actionlint 1.7.7 in ci.yml
- scorecard 5.1.1 in org-scorecard.yml

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: enforce MD041, add standards references to all YAML files

- Enable MD041 (first line heading) — all markdown files already comply
- Add header comment to each workflow YAML with purpose and link to
  the org standard definition that governs it
- Add header comment to dependabot.yml

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: extend compliance audit with CI/automation health survey (#13)

Replaces compliance-audit.yml with compliance-audit-and-improvement.yml,
extending the existing weekly compliance audit with runtime health
telemetry and a forward-looking best practices research phase.

Architecture (3 jobs):

  Job 1 — Compliance Audit (unchanged)
    Deterministic shell script checking all repos against org standards.
    Creates/updates/closes compliance issues per finding.

  Job 2 — Health Survey (new)
    Collects runtime telemetry across all org repos:
    CI run failures (7d), security alerts (Dependabot/secret/code scanning),
    PR staleness, branch protection status, workflow inventory.

  Job 3 — Analyze & Create Issues (Claude, rewritten)
    Six-phase analysis combining both datasets:
    1. Load compliance + health data and org standards
    2. Correlate and categorize findings by severity
    3. Research root causes and automation opportunities
    4. Evaluate against industry best practices and emerging capabilities
       (agentic guardrails, supply chain integrity, reliability SLOs, etc.)
       — outputs only standards proposals, not implementation issues
    5. Create issues: repo-specific go in that repo, org-wide in .github,
       every issue gets the claude label for agent pickup
    6. Summary report to step summary

Issue rules:
- Every issue must have the `claude` label
- Repo-specific issues are created in that repo
- Org-wide and standards proposals go in .github
- Deduplicates against existing open issues
- Max 3 standards-improvement + 3 best-practices proposals per run

Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore(deps): Bump anthropics/claude-code-action from 1.0.83 to 1.0.89 (#22)

Bumps [anthropics/claude-code-action](https://github.com/anthropics/claude-code-action) from 1.0.83 to 1.0.89.
- [Release notes](https://github.com/anthropics/claude-code-action/releases)
- [Commits](https://github.com/anthropics/claude-code-action/compare/v1.0.83...6e2bd52842c65e914eba5c8badd17560bd26b5de)

---
updated-dependencies:
- dependency-name: anthropics/claude-code-action
  dependency-version: 1.0.89
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* feat: split Claude workflow into interactive + issue automation jobs (#54)

* feat: split Claude workflow into interactive + issue automation jobs

The single-job Claude workflow created branches for issue-labeled triggers
but never opened PRs — requiring a human to click through. Split into two
jobs so issue-triggered work runs in automation mode with a prompt that
drives the full lifecycle: implement, create PR, self-review, resolve
comments, check CI, and tag the maintainer.

Updates both the workflow and the ci-standards.md standard definition.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: use CODEOWNERS for maintainer tagging instead of hardcoded username

The claude-issue prompt now reads CODEOWNERS at runtime to determine
who to tag when a PR is ready. This removes the need for per-repo
customization of the prompt.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: require GitHub Discussions on all repos (#53)

* feat: require GitHub Discussions on all repos with standard categories

Elevate Discussions from optional community feature to required org standard.
Add Discussions Configuration section defining required categories (Ideas,
General) and automated ideation workflow integration. Promote has_discussions
audit check from warning to error via REQUIRED_SETTINGS_BOOL.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: require feature-ideation workflow for BMAD Method repos

Add bmad-method ecosystem detection (looks for _bmad/ directory) and
conditionally require feature-ideation.yml workflow. Add CI Standards
section 8 documenting the conditional workflow. Update ecosystem table
in github-settings.md to include bmad-method.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address review comments — severity levels and requirement language

- Extend REQUIRED_SETTINGS_BOOL tuple format to include per-entry severity
  (key:expected:severity:detail) instead of hardcoding all as warning
- Set has_discussions and has_issues to error severity; others remain warning
- Change feature-ideation.yml finding from warning to error for BMAD repos
- Change SHOULD to MUST for BMAD ideation workflow requirement in standards

Addresses CodeRabbit and Copilot review comments on PR #53.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: grant claude-issue job tools to create PRs and check CI (#55)

The claude-issue job had no access to `gh` CLI or file editing tools,
so Claude could implement and push but never actually open a PR.
Added --allowedTools for gh pr create/view, gh run view/watch, cat,
Edit, and Write so the automation prompt can execute end-to-end.

Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: add concurrency guard and comment tools to claude-issue job

- Add concurrency group keyed on issue number to prevent duplicate runs
- Add gh pr comment and gh issue comment to allowedTools so Claude can
  post review replies, resolve threads, and tag code owners
- Remove Bash(cat:*) since the Read tool already covers file reads

Addresses review feedback from CodeRabbit and Copilot across org PRs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: auto-create required labels during compliance audit (#67)

fix: auto-create required labels during compliance audit and settings apply

Adds ensure_required_labels() to compliance-audit.sh so all 6 required
labels (security, dependencies, scorecard, bug, enhancement, documentation)
are idempotently created during each audit run, eliminating the
missing-label-* compliance finding category.

Also extends apply-repo-settings.sh with apply_labels() so the remediation
script covers labels alongside repository settings.

Closes #46

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: don-petry <don-petry@users.noreply.github.com>

* feat: reusable Claude Code workflow with workflows write permission (#77)

feat: extract reusable Claude Code workflow with GH_PAT_WORKFLOWS support

Centralizes the Claude Code prompt and config into a reusable workflow
(claude-code-reusable.yml) so repo-level claude.yml files are thin callers.
Adds github_token input using GH_PAT_WORKFLOWS secret to grant workflows
write permission, unblocking Claude from pushing .github/workflows/ changes.

Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Add Feature Ideation workflow as standard for BMAD-enabled repos (#81)

* feat: add Feature Ideation workflow as a standard for BMAD-enabled repos

Promotes the BMAD Analyst (Mary) feature ideation workflow piloted in
petry-projects/TalkTerm to an org-wide standard for any repo with BMAD
Method installed.

Adds:
- standards/workflows/feature-ideation.yml — the canonical template,
  generalised from TalkTerm. Customisation surface is a single
  PROJECT_CONTEXT env var that describes the project and its market.
- standards/ci-standards.md §8 rewrite — documents the multi-skill
  ideation pipeline (Market Research → Brainstorming → Party Mode →
  Adversarial), the Opus 4.6 model requirement, the github_token
  permissions gotcha, and the show_full_output secrets hazard.
- standards/agent-standards.md — adds a "BMAD Method Workflows"
  section linking the standard from the agent ecosystem docs.

The four critical gotchas baked into the template were each discovered
empirically during the TalkTerm pilot and would silently regress without
the inline comments. Most importantly: the action's auto-generated
claude[bot] App token lacks discussions:write, so the workflow MUST
pass github_token: ${{ secrets.GITHUB_TOKEN }} explicitly or every
Discussion mutation fails silently while the run reports success.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: split feature-ideation into reusable workflow + thin caller stub

Avoids ~600 lines of prompt duplication across every BMAD-enabled repo and
makes the multi-skill ideation pipeline tunable in one place — changes here
propagate to every adopter on next scheduled run.

- .github/workflows/feature-ideation-reusable.yml — the actual reusable
  workflow (workflow_call). Contains both jobs (signal collection +
  analyst), the full Phase 1-8 prompt, and the four critical gotchas
  (Opus 4.6 model, github_token override, no show_full_output, structural
  Phase 2-5 sequence) hard-coded so they cannot regress.
- standards/workflows/feature-ideation.yml — replaced the 600-line copy
  with a ~60-line caller stub that only defines the schedule, the
  workflow_dispatch inputs, and a single required parameter:
  project_context.
- standards/ci-standards.md §8 — documents the reusable + caller stub
  architecture, the inputs/secrets contract, and updated adoption steps.
  Reference implementation pointer updated to note that TalkTerm is now
  also a thin caller stub.

Inputs exposed by the reusable workflow:
- project_context (required) — project description for Mary
- focus_area (default '') — typically wired to workflow_dispatch
- research_depth (default 'standard')
- model (default 'claude-opus-4-6') — escape hatch only
- timeout_minutes (default 60)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(lint): add shellcheck disable for GraphQL variable false positive

The gh api graphql queries use $repo / $owner / $categoryId as GraphQL
variables (not shell expansions), which must remain in single quotes.
shellcheck SC2016 fires anyway — disable it for this script.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(lint): use quoted heredocs for GraphQL queries to satisfy SC2016

actionlint runs shellcheck on the entire run script as one unit and ignores
inline disable directives. Rewriting the gh api graphql calls to use
cat <<'GRAPHQL' heredocs makes the GraphQL variable references ($repo,
$owner, $categoryId) shell-inert without depending on single-quoted
string literals — eliminating the SC2016 false positive.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: expand prompt variables via Actions expressions, add placeholder guard

CodeRabbit caught a critical latent bug inherited from the original TalkTerm
prompt: shell-style $VAR and $(date) syntax inside the action's `prompt:`
input is NOT expanded — the action receives literal text. This silently
broke variable substitution in every prior run, but mattered most for the
new reusable workflow because PROJECT_CONTEXT is now load-bearing.

Changes:
- Replace $PROJECT_CONTEXT, $FOCUS_AREA, $RESEARCH_DEPTH, and $(date ...)
  with ${{ inputs.* }} and ${{ github.run_started_at }} expressions, which
  ARE evaluated by GitHub before passing the prompt to the action.
- Add a "Validate project_context is customised" pre-step that fails fast
  if an adopter copied the caller stub without replacing the TODO
  placeholder. Prevents wasted Opus runs producing generic Discussions.
- scripts/compliance-audit.sh: detect BMAD repos via `_bmad-output/` as
  well as `_bmad/`, matching the broader detection rule documented in
  ci-standards.md §8 (TalkTerm only has `_bmad-output/`).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(lint): drop github.run_started_at (not in actionlint context schema)

The agent can read scan_date from signals.json instead — added a hint
in the Environment section.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(caller): grant cascading permissions on the calling job

CodeRabbit caught: the caller stub had `permissions: {}` at workflow
level and no permissions block on the calling job. Reusable workflows
inherit permissions from the calling job — without an explicit grant,
the reusable workflow's `discussions: write` declaration would have
nothing to apply, and Discussion mutations would fail with FORBIDDEN
just like the original bug we fixed in TalkTerm.

The reusable workflow's job-level permissions are documentation of
what it needs; the caller is what actually grants them.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: use claude_args --model interface; instruct re-query before create

Two more fixes from CodeRabbit review:

1. Model selection via claude_args (the documented v1 interface)
   instead of ANTHROPIC_MODEL env var. claude_args takes precedence over
   the env var per the action's docs, so depending on the env var was
   relying on undocumented behavior. The pinned v1.0.89 happens to honor
   ANTHROPIC_MODEL too (verified in TalkTerm run #3 logs), but the
   documented path is more robust against future action upgrades.

2. Re-query existing Ideas discussions before each create. The signals
   snapshot only fetches the first page of discussions (GraphQL caps
   connections at 100 per page) and only covers the Ideas category, not
   the General fallback. Mary now does a fresh query before each create
   to avoid duplicates in repos with >100 idea threads or where Ideas
   doesn't exist.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: pass GH_PAT_WORKFLOWS to actions/checkout so git push uses workflow-scoped token (#82)

* fix: encode compliance-fix learnings into standards and Claude prompt (#86)

* fix(claude-action): grant administration:write, allow gh api/label create, add standards-conformance prompt rules

* docs(ci-standards): add 'Using Templates' section, SHA lookup procedure, document administration:write

* docs(AGENTS): link standards root and per-topic standards files at top of file

* docs(AGENTS): wrap standards-rule paragraph to satisfy MD013 line-length

* fix(claude-action): yamllint disable for long allowedTools line

* fix(claude-action): remove invalid 'administration' permission scope; document GH_PAT_WORKFLOWS as the actual mechanism

* docs(ci-standards): replace bogus 'administration: write' note with explanation of how admin ops actually work via GH_PAT_WORKFLOWS

* feat(security): add codeql.yml for SAST scanning (#100)

Adds the required CodeQL Analysis workflow for the .github repository.
Scans the `actions` ecosystem (per standard: repos with .github/workflows/*.yml
must scan `actions`). Uses codeql-action@v4.35.1 pinned to SHA per the
Action Pinning Policy.

Closes #39

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: don-petry <don-petry@users.noreply.github.com>

* Replace per-repo CodeQL workflows with GitHub default setup (#103)

* feat(security): replace per-repo CodeQL workflows with GitHub default setup

The org standard previously required every repo to carry a codeql.yml
workflow file. In practice the fleet used a minimal advanced configuration
that added maintenance overhead (SHA pinning, Dependabot bumps, manual
language matrix) without providing anything GitHub's managed default setup
doesn't already cover.

This commit:
- Rewrites ci-standards.md §2 to make default setup the standard
- Deletes .github/workflows/codeql.yml from this repo (added in #100)
- Updates compliance-audit.sh: replaces codeql.yml file existence check
  with code-scanning/default-setup API probe, and flags stray codeql.yml
  files as drift
- Updates apply-rulesets.sh: derives the `CodeQL` required-status-check
  context from the default-setup API instead of workflow file parsing
- Updates apply-repo-settings.sh: adds apply_codeql_default_setup()
  so `--all` runs enable default setup fleet-wide

Repos with a concrete need for advanced setup (custom query packs, path
filters, compiled-language build modes) may opt out by filing a standards
PR documenting the exception.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address review comments from Copilot and CodeRabbit on #103

- Replace placeholder #<this-pr> with #103 in compliance-audit.sh
- Fix apply-repo-settings.sh: docstring now matches behavior (warn and
  continue on failure, not hard fail); add CODEQL_ADVANCED_EXCEPTIONS
  list so approved advanced-setup repos are skipped
- Fix apply-rulesets.sh: distinguish API probe errors from explicit
  "not-configured" state — probe failures now exit nonzero instead of
  silently omitting CodeQL from required checks
- Fix ci-standards.md: remove misleading "coverage" wording from Python
  section; fix MD028 blank line inside blockquote (Lint failure)
- Update github-settings.md: CodeQL check name is now `CodeQL` (default
  setup context), not `Analyze` / `Analyze (<language>)`

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: trigger CodeQL default setup scan on PR

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Auto-respond to all PR review comments without @claude mention (#123)

Remove @claude mention filter so Claude auto-responds to all PR reviews

Instead of requiring reviewers to explicitly mention @claude, Claude now
responds to all issue comments and PR review comments from trusted
contributors (OWNER, MEMBER, COLLABORATOR). Added a claude[bot] exclusion
to prevent infinite feedback loops.

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(ci): move Dependabot exclusion to job-level if in claude-code-reusable.yml (#136)

fix(ci): move dependabot exclusion to job-level if in claude-code-reusable.yml

The claude job was reporting as failed on Dependabot PRs because the
dependabot[bot] check was at the step level, causing the job to start
but all steps to be skipped. GitHub marks such jobs as failed rather
than skipped.

Move the exclusion to the job-level if condition so the entire job is
properly skipped. Also remove the now-redundant step-level if, and
update AGENTS.md to describe the corrected behavior.

Closes #135

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: don-petry <don-petry@users.noreply.github.com>

* chore(deps): Bump anthropics/claude-code-action from 1.0.89 to 1.0.93 (#128)

Bumps [anthropics/claude-code-action](https://github.com/anthropics/claude-code-action) from 1.0.89 to 1.0.93.
- [Release notes](https://github.com/anthropics/claude-code-action/releases)
- [Commits](https://github.com/anthropics/claude-code-action/compare/6e2bd52842c65e914eba5c8badd17560bd26b5de...b47fd721da662d48c5680e154ad16a73ed74d2e0)

---
updated-dependencies:
- dependency-name: anthropics/claude-code-action
  dependency-version: 1.0.93
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot-automerge-petry[bot] <270452309+dependabot-automerge-petry[bot]@users.noreply.github.com>

* feat(claude): trigger Claude to fix CI failures on PRs (#148)

* feat(claude): trigger Claude to fix CI failures on PRs

Add a new `claude-ci-fix` job to the reusable Claude Code workflow that
fires whenever a check run completes with a `failure` conclusion on a
same-repo PR. Claude is prompted to check out the PR branch, diagnose
the failure via logs and annotations, apply a minimal fix, push, and
comment with a summary.

Caller stubs (both the local `.github/workflows/claude.yml` and the
`standards/workflows/claude.yml` template) gain the `check_run:
types: [completed]` trigger needed to activate the new job.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(claude): wrap long prompt lines in yamllint disable/enable

The `prompt:` block in the `claude-ci-fix` job contained a line over
200 characters (329). Wraps it in `# yamllint disable/enable
rule:line-length` comments, matching the pattern already used for
`claude_args` throughout the reusable workflow.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(claude-ci-fix): address Copilot review — null guard, anti-loop, repo placeholder

Three correctness issues raised in PR review:

1. Explicit null guard: add `pull_requests[0] != null` before the repo
   check so the expression is safe when `check_run` fires without any
   associated PR (e.g. pushes to main, external checks).

2. Anti-self-loop: add `!startsWith(..., 'claude-code / claude')` to
   exclude this workflow's own check runs from re-triggering the job,
   preventing an infinite retry cycle if claude-ci-fix itself fails.

3. Concurrency group: replace the bare `${{ pull_requests[0].number }}`
   interpolation with a safe `format()` expression that falls back to
   `run_id` when there is no associated PR.

4. Prompt API path: replace the literal `{owner}/{repo}` placeholder
   with `${{ github.repository }}` so the gh api command Claude is
   instructed to run is immediately executable.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(feature-ideation): add curated reputable source list for Mary (#102)

* feat(feature-ideation): per-repo source list + feed checkpoint via last successful run

Source list (addresses all Copilot/CodeRabbit/don-petry review threads):
- Add standards/feature-ideation-sources.md as a starter template; each
  adopting repo copies it to .github/feature-ideation-sources.md and owns
  it independently (no cross-repo checkout).
- Add sources_file input to the reusable workflow (default:
  .github/feature-ideation-sources.md). Phase 2 prompt reads the repo-
  local file; falls back to open web search if absent.
- Fix three arXiv RSS feed URLs from http:// to https://.
- Update propagation wording in ci-standards.md to reflect per-repo
  ownership and v1 tag model.
- Pin caller stub reusable ref from mutable @v1 to commit SHA ae9709f # v1.
- Add actions: read to gather-signals permissions and caller stub template
  (required for gh run list in same repo).

Feed checkpoint (new — avoids re-reviewing same content every week):
- collect-signals.sh: query gh run list --status=success --limit=1 to
  resolve the previous successful run timestamp; fall back to 30 days ago
  on first run or after a long outage.
- compose-signals.sh: add last_successful_run as arg 10 (schema_version
  shifts to arg 11, truncation_warnings to arg 12).
- signals.schema.json: add last_successful_run field; bump schema version
  1.0.0 → 1.1.0 (SCHEMA_VERSION constant updated in lockstep per bats test).
- Test fixtures (populated, empty-repo, truncated): add last_successful_run
  and bump schema_version to 1.1.0.
- Phase 2 prompt: instruct Mary to filter feed entries to those published
  after last_successful_run; bypass checkpoint if >60 days old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(feature-ideation): validate ISO-8601 format for last_successful_run fallback

The gh stub used in bats tests returns raw fixture JSON without applying
--jq filters, so the captured last_successful_run value was a JSON array
instead of an ISO-8601 timestamp. Add a grep -qE '^[0-9]{4}-...' guard
that falls back to the 30-day default whenever the output is not a valid
date-time string, keeping all existing bats tests green without requiring
every test script to stub the new gh run list call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(collect-signals): align bats stub order with new gh run list call

The feed-checkpoint `gh run list` call added in the previous commit is
now the *first* gh invocation, so every manually-built stub script in
collect-signals.bats needs a corresponding first entry.

- Prepend run-list-last-success.txt to all 5 manual script builders
  (auth-failure, graphql-errors, bot-only-truncation,
  discussions-truncated, no-ideas-category)
- Fix date fallback format: append T00:00:00Z to date_days_ago output
  so the JSON Schema format:date-time constraint is satisfied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compose-signals.bats): update call sites to 12-arg signature

All compose_signals invocations now pass last_successful_run as
the new arg 10, shifting schema_version to 11 and
truncation_warnings to 12. Also adds last_successful_run to the
required-fields assertion in the empty-inputs test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): address CodeRabbit and Copilot review comments

- collect-signals.sh: use WORKFLOW_FILE env var (default: feature-ideation.yml)
  so repos that rename their caller stub can override without a code change;
  capture gh run list stderr in a temp file and log it when the fallback is
  triggered so auth/network failures are distinguishable from first-run
- feature-ideation-reusable.yml: clarify propagation comment — changes reach
  @v1 stubs only after the v1 tag is bumped, not on every next run
- ci-standards.md: align Tier-1 table wording with the @v1 tag-bump model
- standards/workflows/feature-ideation.yml: reword sources_file comment to
  make clear users must uncomment AND change the path for non-default locations;
  show a non-default example path to reduce ambiguity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add self-test feature-ideation stub for dry-run validation

* fix: trailing newline + clean up stub

* fix: pin reusable workflow ref to commit SHA (SonarCloud)

* chore: remove temporary test stub (not for main)

* fix(reusable): guard against empty sources_file in Phase 2 prompt

If a caller passes sources_file: '' the prompt previously rendered a
bare 'Read: ' instruction. Now uses a GitHub Actions expression to
branch: non-empty value emits the Read instruction; empty/omitted
emits a clear fallback note directing Mary to open web search and log
a warning in the step summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): move sources_file expression to env var to respect line-length

The format() expression was 241 chars, over the 200-char yamllint limit.
Moving it to SOURCES_INSTRUCTION in the step env block (where the
expression is still valid) and referencing $SOURCES_INSTRUCTION in the
prompt string brings all lines under 200 chars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): resolve YAML syntax error in sources_file prompt guard

The format() expression with backtick literals inside a GHA expression
caused a YAML mapping-value syntax error at parse time. Replaced with
a plain env var SOURCES_FILE_PATH + shell-style conditional in the prompt
text — no GHA expressions inside the multiline prompt string, fully
YAML-safe and under the 200-char line limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(dotgithub): add feature-ideation caller stub for .github self-test

Adds the Feature Research & Ideation workflow to the .github repo itself,
making it a BMAD-enabled consumer of its own reusable pipeline.

Key configuration:
- project_context: org-level DevX/tooling repo (CI standards, reusable
  workflows, BMAD framework, agent security)
- sources_file: 'standards/feature-ideation-sources.md' — the template
  lives right here, so no copy needed
- dry_run defaults to false (use workflow_dispatch input to enable)
- actions: read permission for feed checkpoint

Note: uses: SHA points to current v1. After this PR merges, bump the
v1 tag to the new merge commit and update the SHA here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>

* fix: correct reusable workflow path syntax (remove duplicate .github) (#154)

* fix: correct reusable workflow path in claude.yml and agent-shield.yml

The workflow references were using an incorrect path with duplicate
'.github/' segment: 'petry-projects/.github/.github/workflows/...'

This caused failures in all child repos trying to call these reusables
because GitHub Actions couldn't find the workflow at that path.

Corrected to: 'petry-projects/.github/workflows/...'

This fix will resolve failing compliance PRs across markets, ContentTwin,
TalkTerm, and bmad-bgreat-suite that pinned these workflows.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* feat: add compliance audit check for reusable workflow path syntax

Adds validation to catch the duplicate .github/ segment issue in reusable
workflow references:
  - BROKEN: uses: petry-projects/.github/.github/workflows/...
  - CORRECT: uses: petry-projects/.github/workflows/...

This check will flag any workflow that incorrectly references reusable
workflows from the org .github repository with the doubled path segment.

This prevents future auto-generated compliance PRs from seeding the
broken path syntax across all org repositories.

Resolves the root cause of widespread CI failures in compliance PRs.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>

* fix(claude-ci-fix): resolve PR via API when check_run payload is empty

* fix(claude-ci-fix): resolve PR via API when check_run payload is empty

- Remove pull_requests[0] != null guard from if condition; GitHub
  frequently omits this array in check_run webhook payloads for
  external checks (SonarCloud, CodeQL, etc.)
- Add Resolve PR number step that falls back to the commits/{sha}/pulls
  API when the payload's pull_requests array is empty
- Fix self-exclusion name filter: was 'claude-code / claude' (wrong
  case); actual check run names start with 'Claude Code'
- Fix concurrency key: was referencing pull_requests[0].number which
  is null when payload is empty; now uses head_sha

* docs: add claude-ci-fix to standard and compliance audit

- Document the third job (claude-ci-fix) in ci-standards.md section 4:
  update jobs list, triggers example, and checkout requirement note
- Extend check_claude_workflow_checkout() to also verify the check_run
  trigger is present — without it claude-ci-fix can never fire

* fix: update auto-rebase template SHA to version containing the reusable workflow

* docs: document OIDC immutability constraint and exempt claude.yml from SHA pinning (#159)

Resolve OIDC immutability constraint and exempt claude.yml from agent modifications

- Document OIDC byte-for-byte validation requirement for .github/workflows/claude.yml
- Add paths-ignore guard to prevent PR triggers on claude.yml-only changes
- Create machine-readable exemption list (standards/workflow-exemptions.json)
- Update agent-standards.md to reference exemption policy
- Fix YAML linting error in auto-rebase.yml (missing EOF newline)

Fixes all CodeRabbit review comments and unblocks 6 downstream auto-rebase pinning PRs.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* fix: restore double .github path in agent-shield and claude reusable refs

fix: restore double .github path in reusable workflow refs

Commit 956b396 incorrectly "fixed" the reusable workflow uses: paths by
removing the second .github segment. The correct format for calling a
reusable in the org's .github repo is:

  petry-projects/.github/.github/workflows/<file>.yml@<ref>

where the first .github is the repo name and the second .github/workflows/
is the path within that repo. The "fix" broke both agent-shield.yml and
claude.yml — all runs since April 21 have failed with 0 jobs (workflow
file issue) in 0 seconds.

Reverts the uses: lines to the pre-956b396 values. The standards/workflows/
templates and compliance-audit.sh already document the double .github as
correct and expected.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: add dedup pre-flight to claude-issue to prevent duplicate PRs (#182)

fix: add dedup pre-flight to claude-issue job to prevent duplicate PRs

Inserts a "Check for existing open PR" step before Run Claude Code in the
claude-issue job. If an open PR already exists for the issue (matched by
claude/issue-NNN-* branch prefix or "Closes #NNN" body search), the step
posts a comment on the issue linking to it and sets an output that causes
Run Claude Code to be skipped via its `if:` condition.

This prevents duplicate PRs when the `claude` label is re-applied on
successive days or retried after a partial run. Concurrency
cancel-in-progress already handles parallel runs; this handles sequential
re-triggers which concurrency cannot catch.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: trigger Claude on CodeRabbit and Copilot review comments (#198)

The pull_request_review_comment condition previously required OWNER/MEMBER/COLLABORATOR
author_association, which excluded both bots. Adds coderabbitai[bot] and Copilot as
allowed senders so Claude automatically addresses their inline findings.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(deps): Bump anthropics/claude-code-action from 1.0.97 to 1.0.115 (#150)

Bumps [anthropics/claude-code-action](https://github.com/anthropics/claude-code-action) from 1.0.97 to 1.0.115.
- [Release notes](https://github.com/anthropics/claude-code-action/releases)
- [Commits](https://github.com/anthropics/claude-code-action/compare/905d4eb99ab3d43143d74fb0dcae537f29ac330a...9db782c3a17ef2bfc274cd17411bc3e0a5ba1345)

---
updated-dependencies:
- dependency-name: anthropics/claude-code-action
  dependency-version: 1.0.101
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot-automerge-petry[bot] <270452309+dependabot-automerge-petry[bot]@users.noreply.github.com>

* feat(claude-code-reusable): enable rebases in interactive job

Allow the interactive claude job to handle PRs that need a rebase or pull
before pushing. PR petry-projects/.github#166 hit this when auto-rebase
pushed merge commits to the remote during the run and Claude could not
fast-forward.

- fetch-depth: 1 -> 0 so rebase/merge against main works.
- Add explicit --allowedTools covering git fetch/pull/rebase/merge plus
  the standard git, gh CLI, and Edit/Write/Read surface. Setting
  claude_args.--allowedTools replaces the action defaults, so the list is
  written out comprehensively.

https://claude.ai/code/session_01Udspx48vYhjiEG3fnraMKV

* chore(deps): Bump anthropics/claude-code-action from 1.0.115 to 1.0.119 (#226)

Bumps [anthropics/claude-code-action](https://github.com/anthropics/claude-code-action) from 1.0.115 to 1.0.119.
- [Release notes](https://github.com/anthropics/claude-code-action/releases)
- [Commits](https://github.com/anthropics/claude-code-action/compare/9db782c3a17ef2bfc274cd17411bc3e0a5ba1345...476e359e6203e73dad705c8b322e333fabbd7416)

---
updated-dependencies:
- dependency-name: anthropics/claude-code-action
  dependency-version: 1.0.119
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dependabot-automerge-petry[bot] <270452309+dependabot-automerge-petry[bot]@users.noreply.github.com>

* fix(claude-code-reusable): broaden allowedTools, sync ci-standards.md

Address Copilot review on #235:

1. --allowedTools was a narrow allowlist that would hard-fail on any
   missing git/gh verb (since the flag replaces action defaults). Broaden
   to Bash(git:*),Bash(gh:*) plus common shell utilities and the full
   core tool set (Edit, Write, Read, Grep, Glob, LS, MultiEdit,
   WebFetch, WebSearch, Task, TodoWrite, BashOutput, KillBash).

2. standards/ci-standards.md was documenting fetch-depth: 1 for the
   interactive claude job and had no allowedTools snippet. Sync the
   example with the actual reusable workflow and add a comment
   explaining why the allowlist is intentionally broad.

https://claude.ai/code/session_01Udspx48vYhjiEG3fnraMKV

* docs(ci-standards): bump claude-code-action examples to v1.0.119

CodeRabbit flagged that standards/ci-standards.md still showed
anthropics/claude-code-action@6e2bd528... # v1.0.89 in the claude
and claude-issue job examples, while the actual reusable workflow uses
@476e359e6203e73dad705c8b322e333fabbd7416 # v1.0.119 (bumped by
Dependabot #226). Sync the docs.

https://claude.ai/code/session_01Udspx48vYhjiEG3fnraMKV

* docs(ci-standards): sync Version Inconsistencies table to v1.0.119

CodeRabbit flagged the "Version Inconsistencies" table (line 1045)
still listed Claude Code Action as v1.0.89 (6e2bd528), inconsistent
with the v1.0.119 (476e359e) pin documented in the example workflows
just bumped in 9af3e4e.

https://claude.ai/code/session_01Udspx48vYhjiEG3fnraMKV

* chore: deprecate pr-review-agent — remove all traces

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* feat: make pr-review-mention an org standard (#237)

* feat: make pr-review-mention an org standard with reusable workflow

- Extract all logic from pr-review-mention.yml into pr-review-mention-reusable.yml (org single source of truth)
- Slim pr-review-mention.yml down to a thin caller stub (local ref pattern, matching auto-rebase.yml)
- Add standards/workflows/pr-review-mention.yml canonical template for other repos (@v1 reference)
- Add pr-review-mention.yml to REQUIRED_WORKFLOWS and centralized stub checks in compliance-audit.sh
- Document in ci-standards.md: template table, required-workflow count (6→7), and §10 with full spec
- Add scripts/deploy-standard-workflows.sh to push standard stubs to all org repos in one command

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix: remove unused counter vars (SC2034), add trailing newline to codeowners-standard

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix: address Gemini review comments on deploy-standard-workflows.sh

- Fix claude.yml compliance check: derive uses: from template (not stem-reusable
  heuristic), so the claude→claude-code-reusable name exception is handled automatically
- Combine two API calls (SHA + content) into one fetch_existing call with tab-split output
- Fix base64 portability: try -w 0 (GNU), fall back to -b 0 (BSD/macOS)
- Increase repo list limit to 500 for larger orgs
- Remove unused counter variables (already fixed in prior commit; this replaces the old approach)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix: address Copilot review comments

- Declare GH_PAT_WORKFLOWS in workflow_call secrets block (matching other reusables)
- Clarify fork-PR guard docs: only review_requested path excludes forks; comment
  triggers are base-repo-only by GitHub's event model, protected by trust check
- Fix 'SHA' → 'tag' in standards/workflows/pr-review-mention.yml header comment
- Add --no-archived to gh repo list in deploy script
- Switch --field to --raw-field for content/sha/message to avoid form-encoding issues
  with base64's + and / characters

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* fix(claude): add copilot-pull-request-reviewer and gemini-code-assist to bot allow list (#238)

* fix(claude): add copilot-pull-request-reviewer and gemini-code-assist to bot allow list

The pull_request_review_comment condition allowed coderabbitai[bot] and
Copilot but missed two other active review bots:

- copilot-pull-request-reviewer[bot]: GitHub Copilot PR review app
- gemini-code-assist[bot]: Google Gemini code review app

Both are installed org-wide and regularly leave actionable review
comments that Claude should respond to. Without these entries their
comments caused the 'claude' job to be skipped every time.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(claude): guard bot allow list against fork PRs

Per security review: bot logins have author_association 'NONE', so
the new allow list could allow secrets-bearing runs triggered by bot
comments on fork PRs. Add a same-repo guard so bot-triggered reviews
only fire when the PR head is within the same repo.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(claude-ci-fix): correct self-loop guard and add fork PR trust gate

- Fix self-loop: check run names for reusable workflows are prefixed by
  the calling job name (e.g. 'claude-code / claude-ci-fix'), not by the
  workflow display name 'Claude Code'; switch to startsWith 'claude-code / '
- Add fork PR trust gate in Resolve PR number step: verify head.repo
  matches target repo before running Claude with privileged credentials

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix(feature-ideation): address Copilot + CodeRabbit review on PR #85 (18 fixes, 17 new tests) (#85)

* test(feature-ideation): extract bash to scripts, add schema + 92 bats tests

Refactors the reusable feature-ideation workflow's parsing surface from
an inline 600-line YAML heredoc into testable scripts with deterministic
contracts. Every defect that previously required post-merge review can
now fail in CI before adopters notice.

Why
---
The prior reusable workflow used `2>/dev/null || echo '[]'` for every
gh / GraphQL call, which silently downgraded auth failures, rate limits,
network outages, and GraphQL schema drift to empty arrays. The pipeline
would "succeed" while producing useless signals — and Mary's Discussion
posts would silently degrade across every BMAD repo on the org. The
prompt also instructed Mary to "use fuzzy matching" against existing
Ideas Discussions in her head, which is non-deterministic and untestable.

Risk register (probability × impact, scale 1–9):
  R1=9  swallow-all-errors gh wrapper
  R2=6  literal $() inside YAML direct prompt
  R3=6  no signals.json schema
  R4=6  jq --argjson crash on empty input
  R5=6  fuzzy match in Mary's prompt → duplicate Discussions
  R6=6  retry idempotency hole
  R7=6  GraphQL errors[]/null data not detected
  R8=4  GraphQL partial errors silently accepted
  R10=3 bot filter only catches dependabot/github-actions
  R11=4 pagination silently truncates

What's new
----------
.github/scripts/feature-ideation/
  collect-signals.sh         Orchestrator (replaces inline heredoc)
  validate-signals.py        JSON Schema 2020-12 validator
  match-discussions.sh       Deterministic Jaccard matcher (kills R5/R6)
  discussion-mutations.sh    create/comment/label wrappers + DRY_RUN mode
  lint-prompt.sh             Catches unescaped $() / ${VAR} in prompt blocks
  lib/gh-safe.sh             Defensive gh wrapper, fails loud on every
                             documented failure mode (kills R1, R7, R8)
  lib/compose-signals.sh     Validates JSON inputs before jq composition
  lib/filter-bots.sh         Extensible bot author filter (kills R10)
  lib/date-utils.sh          Cross-platform date helpers
  README.md                  Maintainer docs

.github/schemas/signals.schema.json
  Pinned producer/consumer contract for signals.json (Draft 2020-12).
  CI rejects any drift; the runtime signals.json is also validated by
  the workflow before being handed to Mary.

.github/workflows/feature-ideation-reusable.yml
  Rewritten. Adds a self-checkout of petry-projects/.github so the
  scripts above are available in the runner. Replaces inline bash with
  collect-signals.sh + validate-signals.py. Adds RUN_DATE / SIGNALS_PATH /
  PROPOSALS_PATH / MATCH_PLAN_PATH / TOOLING_DIR env vars passed to
  claude-code-action via env: instead of unescaped shell expansions in
  the prompt body. Adds dry_run input that flows through to
  discussion-mutations.sh, which logs every planned action to a JSONL
  audit log instead of executing — uploaded as the dry-run-log artifact.

.github/workflows/feature-ideation-tests.yml
  New CI gate, path-filtered. Runs shellcheck, lint-prompt, schema
  fixture validation, and the full bats suite on every PR that touches
  the feature-ideation surface.

standards/workflows/feature-ideation.yml
  Updated caller stub template. Adds dry_run workflow_dispatch input
  so adopters get safe smoke-testing for free. Existing TalkTerm caller
  stub continues to work unchanged (dry_run defaults to false).

test/workflows/feature-ideation/
  92 bats tests across 9 suites. 14 GraphQL/REST response fixtures.
  5 expected signals.json fixtures (3 valid + 2 INVALID for negative
  schema testing). Programmable gh PATH stub with single-call and
  multi-call modes for integration testing.

  | Suite                       | Tests | Risks closed       |
  |-----------------------------|------:|--------------------|
  | gh-safe.bats                |    19 | R1, R7, R8         |
  | compose-signals.bats        |     8 | R3, R4             |
  | filter-bots.bats            |     5 | R10                |
  | date-utils.bats             |     7 | R9                 |
  | collect-signals.bats        |    14 | R1, R3, R4, R7, R11|
  | match-discussions.bats      |    13 | R5, R6             |
  | discussion-mutations.bats   |    10 | DRY_RUN contract   |
  | lint-prompt.bats            |     8 | R2                 |
  | signals-schema.bats         |     8 | R3                 |
  | TOTAL                       |    92 |                    |

Test results: 92 passing, 0 failing, 0 skipped. Run with:
  bats test/workflows/feature-ideation/

Backwards compatibility
-----------------------
The reusable workflow's input surface is unchanged for existing callers
(TalkTerm continues to work with no edits). The new dry_run input is
optional and defaults to false. Adopters who copy the new standards
caller stub get dry_run support automatically.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test(feature-ideation): use bash -c instead of sh -c in env-extension test

CI failure on the previous commit: 91/92 passing, 1 failing.

The filter-bots env-extension test used `sh -c` to source filter-bots.sh
in a sub-shell with FEATURE_IDEATION_BOT_AUTHORS set. On macOS this works
because /bin/sh is bash. On Ubuntu (CI), /bin/sh is dash, which does not
support `set -o pipefail`, so sourcing filter-bots.sh produced:

  sh: 12: set: Illegal option -o pipefail

Fixed by switching to `bash -c`. All scripts already use
`#!/usr/bin/env bash` shebangs; this is the only place a sub-shell was
spawned via `sh`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(feature-ideation): address Copilot review on PR #85 (11 fixes + 16 tests)

Triaged 14 inline comments from Copilot's review of #85; two were already
fixed by the tooling_ref→v1 commit, the remaining 11 are addressed here.

Critical bug fixes
------------------

1. lint-prompt.sh now scans claude-code-action v1 `prompt:` blocks in
   addition to v0 `direct_prompt:`. The reusable workflow uses `prompt:`
   so the linter was silently allowing R2 regressions on the very file
   it was supposed to protect. Added two regression tests covering both
   the v1 form and a clean v1 form passes.

2. add_label_to_discussion now sends labelIds as a proper JSON array via
   gh_safe_graphql_input (new helper). Previously used `gh -f labelIds=`
   which sent the literal string `["L_1"]` and the GraphQL API would have
   rejected the mutation at runtime. Added a test that captures gh's
   stdin and asserts the variables block contains a length-1 array.

3. validate-signals.py now registers a `date-time` format checker via
   FormatChecker so the `format: date-time` keyword in signals.schema.json
   is actually enforced. Draft202012Validator does NOT enforce formats
   by default, and the default FormatChecker omits date-time entirely.
   Used an inline checker (datetime.fromisoformat with Z normalisation)
   to avoid pulling in rfc3339-validator. Added two regression tests:
   one for an invalid timestamp failing, one for a clean timestamp
   passing.

4. gh_safe_graphql --jq path no longer swallows jq filter errors with
   `|| true`. Filter typos / wrong paths now exit non-zero instead of
   silently returning []. Added a regression test using a deliberately
   broken filter.

5. collect-signals.sh now computes the open-issue truncation warning
   BEFORE filter_bots_apply. Previously, a result set composed entirely
   of bots could drop below ISSUE_LIMIT after filtering and mask real
   truncation. Added an integration test with all-bot fixtures.

6. match-discussions.sh now validates MATCH_THRESHOLD as a non-negative
   number in [0, 1] before passing to Python. A typo previously surfaced
   as an opaque traceback. Added regression tests for non-numeric input,
   out-of-range input, and boundary values 0 and 1.

Cleanup
-------

7. Removed dead bash `normalize_title` / `jaccard_similarity` functions
   from match-discussions.sh — the actual matching is implemented in the
   embedded Python block and the bash helpers were never called.

8. Schema $id corrected from petry-projects/TalkTerm/... to the canonical
   petry-projects/.github location.

9. signals-schema.bats "validator script exists and is executable" test
   now actually checks the `-x` bit (was only checking `-f` and `-r`).

10. README + filter-bots.sh comments now describe the bot list as a
    "blocklist" (it removes matching authors) instead of "allowlist".

11. test/workflows/feature-ideation/stubs/gh now logs argv with `printf
    '%q '` so each invocation is shell-quoted and re-parseable, matching
    its documentation. Previously logged `$*` which lost arg boundaries.

New helper
----------

gh_safe_graphql_input — same defensive contract as gh_safe_graphql, but
takes a fully-formed JSON request body via stdin instead of -f/-F flags.
Use for mutations whose variables include arrays (e.g. labelIds: [ID!]!)
that gh's flag-based interface cannot express. Five new tests cover
its happy path and every documented failure mode.

Tests
-----

Test count: 92 → 108 (16 new regression tests, all green). Run with:
  bats test/workflows/feature-ideation/

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(feature-ideation): address CodeRabbit review on PR #85 (7 fixes + 1 test)

Triaged 13 inline comments from CodeRabbit's review of #85; 6 of them
overlapped with Copilot's review and were already fixed by bcaa579. The
remaining 7 are addressed here.

Fixes
-----

1. lint-prompt.sh: ${VAR} branch lookbehind was inconsistent with the
   $(...) branch — only rejected $$VAR but not \${VAR}. Both branches
   now use [\\$] so backslash-escaped and dollar-escaped forms are
   skipped uniformly.

2. filter-bots.sh: FEATURE_IDEATION_BOT_AUTHORS CSV entries are now
   trimmed of leading/trailing whitespace before being added to the
   blocklist, so "bot1, bot2" matches both bots correctly instead of
   keeping a literal " bot2" entry.

3. validate-signals.py: malformed signals JSON now exits 2 (file/data
   error) to match the documented contract, instead of 1 (which means
   schema validation error).

4. README.md: corrected the workflow filename reference from
   feature-ideation.yml to feature-ideation-reusable.yml, and reworded
   the table cell that contained `\|\|` (escaped pipes that don't
   render correctly in some Markdown engines) to use plain prose. Also
   noted that lint-prompt scans both v0 `direct_prompt:` and v1 `prompt:`.

5. collect-signals.sh: added an explicit comment above SCHEMA_VERSION
   documenting the lockstep requirement with signals.schema.json's
   $comment version annotation. Backed by a new bats test that parses
   both files and asserts they match.

6. signals.schema.json: added $comment "version: 1.0.0" annotation so
   the schema file declares its own version explicitly. Used $comment
   instead of a custom keyword to keep Draft202012 compliance.

7. test/workflows/feature-ideation/match-discussions.bats: build_signals
   helper now computes the discussions count from the array length
   instead of hardcoding 0, so the fixture satisfies its own contract
   (cosmetic — the matcher only reads .items, but contract hygiene
   matters in test scaffolding).

8. test/workflows/feature-ideation/gh-safe.bats: removed the `|| true`
   suffix on the rest-failure assertion that made it always pass.
   Now uses --separate-stderr to capture stderr and asserts the
   structured `[gh-safe][rest-failure]` prefix is emitted on the auth
   failure path. Required `bats_require_minimum_version 1.5.0` to
   suppress the bats-core warning about flag usage.

Tests
-----

Test count: 108 → 109 (one new test for SCHEMA_VERSION ↔ schema sync).
All 109 passing locally. Run with:
  bats test/workflows/feature-ideation/

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(feature-ideation): address CodeRabbit re-review on PR #85 (15 fixes + 5 new tests)

Critical/major:
- collect-signals.sh: validate ISSUE_LIMIT/PR_LIMIT/DISCUSSION_LIMIT are
  positive integers; tighten REPO validation with strict ^[^/]+/[^/]+$ regex
- compose-signals.sh: enforce array type (jq 'type == "array"') not just
  valid JSON so objects/strings don't silently produce wrong counts
- date-utils.sh: guard $# before reading $1 to prevent set -u abort on
  zero-arg calls
- filter-bots.sh: replace unquoted array expansion with IFS=',' read -r -a
  to prevent pathname-globbing against filesystem entries
- gh-safe.sh: bounds-check args[i+1] before --jq dereference; add $# guard
  to gh_safe_graphql_input() to prevent nounset abort
- lint-prompt.sh: recognise YAML chomping modifiers (|-,|+,>-,>+) in
  prompt_marker regex; replace [^}]* GH-expression stripper with a stateful
  scanner that handles nested braces; preserve exit-2 over exit-1 in main()
- match-discussions.sh: wrap json.load calls in try/except for structured
  error exit-2 instead of Python traceback; skip discussions without an id;
  switch from greedy per-proposal to similarity-sorted global optimal matching
- validate-signals.py: catch OSError on read_text() to preserve exit-2
  contract; add -> bool return type annotation to _check_date_time

Docs:
- README.md: update lint command to mention both direct_prompt: and prompt:;
  fix Mary's prompt pointer to feature-ideation-reusable.yml

Tests (+5 new, 109 → 114 total):
- lint-prompt.bats: missing-file-before-lint-failing-file exits 2; YAML
  chomping modifiers detected; nested GH expressions don't false-positive
- match-discussions.bats: malformed signals JSON exits non-zero; malformed
  proposals JSON exits non-zero
- signals-schema.bats: truncated/malformed JSON exits 2 not 1
- date-utils.bats: use date_today helper instead of raw date -u
- stubs/gh: prefer TT_TMP/BATS_TEST_TMPDIR for counter file isolation

Co-authored-by: don-petry <don-petry@users.noreply.github.com>

* fix(feature-ideation): simplify error-envelope check and harden gh stub

Collapse the redundant outer+inner jq guard in gh_safe_graphql into the
single-expression form already used by gh_safe_graphql_input, making
both functions consistent.

Add a fail-fast check to the gh stub so that setting GH_STUB_SCRIPT to
a nonexistent path produces an immediate error instead of silently
falling through to single-call mode and masking test misconfiguration.
Add a bats test that pins the new behaviour.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: don-petry <don-petry@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* feat(claude): add claude-fix-review-comments job for bot review responses (#245)

* feat(claude): add claude-fix-review-comments job for bot review responses

Add a dedicated `claude-fix-review-comments` job that automatically
processes review comments left by bots (CodeRabbit, Copilot, Gemini).

Previously the `claude` job's if-condition allowed these bots but the
claude-code-action always exited early ("Trigger result: false") because
none of the bots mention `@claude` in their comments. The job fired but
did no useful work.

Changes:
- Remove bot logins from the `claude` interactive-mode job's condition.
  Human OWNER/MEMBER/COLLABORATOR review comments still trigger that job
  (they use `@claude` in the comment body to get a response).
- Add `claude-fix-review-comments` job that fires on pull_request_review_comment
  from the whitelisted bots, with a direct prompt that instructs Claude to:
  1. Fetch all open review threads via GraphQL (collecting node IDs)
  2. Check out the PR branch
  3. Address each unresolved thread (applying suggestions, making fixes)
  4. Commit and push
  5. Resolve each addressed thread via GraphQL resolveReviewThread mutation
  6. Wait for CI, fix any failures, repeat
  7. Re-check for new threads after each push
  8. Post a summary comment when done
- Concurrency group per PR number with cancel-in-progress so that a new
  batch of bot comments cancels a prior run (the new run will address all
  open threads anyway).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(claude): rebase PR branch onto latest base before addressing review comments

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(claude-fix-review-comments): add allowedTools, fix pagination, guard empty commit

- Add claude_args with --allowedTools covering gh pr checkout, gh pr
  view, gh pr comment, gh pr checks, gh run view/list/watch, gh api,
  git operations, Edit, and Write — required for every command the
  prompt issues; without this Claude refuses all Bash tool calls and
  the automation silently fails.
- Bump reviewThreads(first:100) → first:250 (GraphQL max) so threads
  beyond 100 are not silently dropped on large PRs.
- Guard the commit with git diff --cached --quiet to avoid a non-zero
  exit when there are no staged changes (all threads needed human
  input); configure g…
don-petry added a commit that referenced this pull request Jun 11, 2026
)

* feat(feature-ideation): per-repo source list + feed checkpoint via last successful run

Source list (addresses all Copilot/CodeRabbit/don-petry review threads):
- Add standards/feature-ideation-sources.md as a starter template; each
  adopting repo copies it to .github/feature-ideation-sources.md and owns
  it independently (no cross-repo checkout).
- Add sources_file input to the reusable workflow (default:
  .github/feature-ideation-sources.md). Phase 2 prompt reads the repo-
  local file; falls back to open web search if absent.
- Fix three arXiv RSS feed URLs from http:// to https://.
- Update propagation wording in ci-standards.md to reflect per-repo
  ownership and v1 tag model.
- Pin caller stub reusable ref from mutable @v1 to commit SHA ae9709f # v1.
- Add actions: read to gather-signals permissions and caller stub template
  (required for gh run list in same repo).

Feed checkpoint (new — avoids re-reviewing same content every week):
- collect-signals.sh: query gh run list --status=success --limit=1 to
  resolve the previous successful run timestamp; fall back to 30 days ago
  on first run or after a long outage.
- compose-signals.sh: add last_successful_run as arg 10 (schema_version
  shifts to arg 11, truncation_warnings to arg 12).
- signals.schema.json: add last_successful_run field; bump schema version
  1.0.0 → 1.1.0 (SCHEMA_VERSION constant updated in lockstep per bats test).
- Test fixtures (populated, empty-repo, truncated): add last_successful_run
  and bump schema_version to 1.1.0.
- Phase 2 prompt: instruct Mary to filter feed entries to those published
  after last_successful_run; bypass checkpoint if >60 days old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(feature-ideation): validate ISO-8601 format for last_successful_run fallback

The gh stub used in bats tests returns raw fixture JSON without applying
--jq filters, so the captured last_successful_run value was a JSON array
instead of an ISO-8601 timestamp. Add a grep -qE '^[0-9]{4}-...' guard
that falls back to the 30-day default whenever the output is not a valid
date-time string, keeping all existing bats tests green without requiring
every test script to stub the new gh run list call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(collect-signals): align bats stub order with new gh run list call

The feed-checkpoint `gh run list` call added in the previous commit is
now the *first* gh invocation, so every manually-built stub script in
collect-signals.bats needs a corresponding first entry.

- Prepend run-list-last-success.txt to all 5 manual script builders
  (auth-failure, graphql-errors, bot-only-truncation,
  discussions-truncated, no-ideas-category)
- Fix date fallback format: append T00:00:00Z to date_days_ago output
  so the JSON Schema format:date-time constraint is satisfied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compose-signals.bats): update call sites to 12-arg signature

All compose_signals invocations now pass last_successful_run as
the new arg 10, shifting schema_version to 11 and
truncation_warnings to 12. Also adds last_successful_run to the
required-fields assertion in the empty-inputs test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): address CodeRabbit and Copilot review comments

- collect-signals.sh: use WORKFLOW_FILE env var (default: feature-ideation.yml)
  so repos that rename their caller stub can override without a code change;
  capture gh run list stderr in a temp file and log it when the fallback is
  triggered so auth/network failures are distinguishable from first-run
- feature-ideation-reusable.yml: clarify propagation comment — changes reach
  @v1 stubs only after the v1 tag is bumped, not on every next run
- ci-standards.md: align Tier-1 table wording with the @v1 tag-bump model
- standards/workflows/feature-ideation.yml: reword sources_file comment to
  make clear users must uncomment AND change the path for non-default locations;
  show a non-default example path to reduce ambiguity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add self-test feature-ideation stub for dry-run validation

* fix: trailing newline + clean up stub

* fix: pin reusable workflow ref to commit SHA (SonarCloud)

* chore: remove temporary test stub (not for main)

* fix(reusable): guard against empty sources_file in Phase 2 prompt

If a caller passes sources_file: '' the prompt previously rendered a
bare 'Read: ' instruction. Now uses a GitHub Actions expression to
branch: non-empty value emits the Read instruction; empty/omitted
emits a clear fallback note directing Mary to open web search and log
a warning in the step summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): move sources_file expression to env var to respect line-length

The format() expression was 241 chars, over the 200-char yamllint limit.
Moving it to SOURCES_INSTRUCTION in the step env block (where the
expression is still valid) and referencing $SOURCES_INSTRUCTION in the
prompt string brings all lines under 200 chars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): resolve YAML syntax error in sources_file prompt guard

The format() expression with backtick literals inside a GHA expression
caused a YAML mapping-value syntax error at parse time. Replaced with
a plain env var SOURCES_FILE_PATH + shell-style conditional in the prompt
text — no GHA expressions inside the multiline prompt string, fully
YAML-safe and under the 200-char line limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(dotgithub): add feature-ideation caller stub for .github self-test

Adds the Feature Research & Ideation workflow to the .github repo itself,
making it a BMAD-enabled consumer of its own reusable pipeline.

Key configuration:
- project_context: org-level DevX/tooling repo (CI standards, reusable
  workflows, BMAD framework, agent security)
- sources_file: 'standards/feature-ideation-sources.md' — the template
  lives right here, so no copy needed
- dry_run defaults to false (use workflow_dispatch input to enable)
- actions: read permission for feed checkpoint

Note: uses: SHA points to current v1. After this PR merges, bump the
v1 tag to the new merge commit and update the SHA here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
don-petry added a commit that referenced this pull request Jun 11, 2026
)

* feat(feature-ideation): per-repo source list + feed checkpoint via last successful run

Source list (addresses all Copilot/CodeRabbit/don-petry review threads):
- Add standards/feature-ideation-sources.md as a starter template; each
  adopting repo copies it to .github/feature-ideation-sources.md and owns
  it independently (no cross-repo checkout).
- Add sources_file input to the reusable workflow (default:
  .github/feature-ideation-sources.md). Phase 2 prompt reads the repo-
  local file; falls back to open web search if absent.
- Fix three arXiv RSS feed URLs from http:// to https://.
- Update propagation wording in ci-standards.md to reflect per-repo
  ownership and v1 tag model.
- Pin caller stub reusable ref from mutable @v1 to commit SHA ae9709f # v1.
- Add actions: read to gather-signals permissions and caller stub template
  (required for gh run list in same repo).

Feed checkpoint (new — avoids re-reviewing same content every week):
- collect-signals.sh: query gh run list --status=success --limit=1 to
  resolve the previous successful run timestamp; fall back to 30 days ago
  on first run or after a long outage.
- compose-signals.sh: add last_successful_run as arg 10 (schema_version
  shifts to arg 11, truncation_warnings to arg 12).
- signals.schema.json: add last_successful_run field; bump schema version
  1.0.0 → 1.1.0 (SCHEMA_VERSION constant updated in lockstep per bats test).
- Test fixtures (populated, empty-repo, truncated): add last_successful_run
  and bump schema_version to 1.1.0.
- Phase 2 prompt: instruct Mary to filter feed entries to those published
  after last_successful_run; bypass checkpoint if >60 days old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(feature-ideation): validate ISO-8601 format for last_successful_run fallback

The gh stub used in bats tests returns raw fixture JSON without applying
--jq filters, so the captured last_successful_run value was a JSON array
instead of an ISO-8601 timestamp. Add a grep -qE '^[0-9]{4}-...' guard
that falls back to the 30-day default whenever the output is not a valid
date-time string, keeping all existing bats tests green without requiring
every test script to stub the new gh run list call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(collect-signals): align bats stub order with new gh run list call

The feed-checkpoint `gh run list` call added in the previous commit is
now the *first* gh invocation, so every manually-built stub script in
collect-signals.bats needs a corresponding first entry.

- Prepend run-list-last-success.txt to all 5 manual script builders
  (auth-failure, graphql-errors, bot-only-truncation,
  discussions-truncated, no-ideas-category)
- Fix date fallback format: append T00:00:00Z to date_days_ago output
  so the JSON Schema format:date-time constraint is satisfied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compose-signals.bats): update call sites to 12-arg signature

All compose_signals invocations now pass last_successful_run as
the new arg 10, shifting schema_version to 11 and
truncation_warnings to 12. Also adds last_successful_run to the
required-fields assertion in the empty-inputs test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): address CodeRabbit and Copilot review comments

- collect-signals.sh: use WORKFLOW_FILE env var (default: feature-ideation.yml)
  so repos that rename their caller stub can override without a code change;
  capture gh run list stderr in a temp file and log it when the fallback is
  triggered so auth/network failures are distinguishable from first-run
- feature-ideation-reusable.yml: clarify propagation comment — changes reach
  @v1 stubs only after the v1 tag is bumped, not on every next run
- ci-standards.md: align Tier-1 table wording with the @v1 tag-bump model
- standards/workflows/feature-ideation.yml: reword sources_file comment to
  make clear users must uncomment AND change the path for non-default locations;
  show a non-default example path to reduce ambiguity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add self-test feature-ideation stub for dry-run validation

* fix: trailing newline + clean up stub

* fix: pin reusable workflow ref to commit SHA (SonarCloud)

* chore: remove temporary test stub (not for main)

* fix(reusable): guard against empty sources_file in Phase 2 prompt

If a caller passes sources_file: '' the prompt previously rendered a
bare 'Read: ' instruction. Now uses a GitHub Actions expression to
branch: non-empty value emits the Read instruction; empty/omitted
emits a clear fallback note directing Mary to open web search and log
a warning in the step summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): move sources_file expression to env var to respect line-length

The format() expression was 241 chars, over the 200-char yamllint limit.
Moving it to SOURCES_INSTRUCTION in the step env block (where the
expression is still valid) and referencing $SOURCES_INSTRUCTION in the
prompt string brings all lines under 200 chars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): resolve YAML syntax error in sources_file prompt guard

The format() expression with backtick literals inside a GHA expression
caused a YAML mapping-value syntax error at parse time. Replaced with
a plain env var SOURCES_FILE_PATH + shell-style conditional in the prompt
text — no GHA expressions inside the multiline prompt string, fully
YAML-safe and under the 200-char line limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(dotgithub): add feature-ideation caller stub for .github self-test

Adds the Feature Research & Ideation workflow to the .github repo itself,
making it a BMAD-enabled consumer of its own reusable pipeline.

Key configuration:
- project_context: org-level DevX/tooling repo (CI standards, reusable
  workflows, BMAD framework, agent security)
- sources_file: 'standards/feature-ideation-sources.md' — the template
  lives right here, so no copy needed
- dry_run defaults to false (use workflow_dispatch input to enable)
- actions: read permission for feed checkpoint

Note: uses: SHA points to current v1. After this PR merges, bump the
v1 tag to the new merge commit and update the SHA here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
don-petry added a commit that referenced this pull request Jun 13, 2026
)

* feat(feature-ideation): per-repo source list + feed checkpoint via last successful run

Source list (addresses all Copilot/CodeRabbit/don-petry review threads):
- Add standards/feature-ideation-sources.md as a starter template; each
  adopting repo copies it to .github/feature-ideation-sources.md and owns
  it independently (no cross-repo checkout).
- Add sources_file input to the reusable workflow (default:
  .github/feature-ideation-sources.md). Phase 2 prompt reads the repo-
  local file; falls back to open web search if absent.
- Fix three arXiv RSS feed URLs from http:// to https://.
- Update propagation wording in ci-standards.md to reflect per-repo
  ownership and v1 tag model.
- Pin caller stub reusable ref from mutable @v1 to commit SHA ae9709f # v1.
- Add actions: read to gather-signals permissions and caller stub template
  (required for gh run list in same repo).

Feed checkpoint (new — avoids re-reviewing same content every week):
- collect-signals.sh: query gh run list --status=success --limit=1 to
  resolve the previous successful run timestamp; fall back to 30 days ago
  on first run or after a long outage.
- compose-signals.sh: add last_successful_run as arg 10 (schema_version
  shifts to arg 11, truncation_warnings to arg 12).
- signals.schema.json: add last_successful_run field; bump schema version
  1.0.0 → 1.1.0 (SCHEMA_VERSION constant updated in lockstep per bats test).
- Test fixtures (populated, empty-repo, truncated): add last_successful_run
  and bump schema_version to 1.1.0.
- Phase 2 prompt: instruct Mary to filter feed entries to those published
  after last_successful_run; bypass checkpoint if >60 days old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(feature-ideation): validate ISO-8601 format for last_successful_run fallback

The gh stub used in bats tests returns raw fixture JSON without applying
--jq filters, so the captured last_successful_run value was a JSON array
instead of an ISO-8601 timestamp. Add a grep -qE '^[0-9]{4}-...' guard
that falls back to the 30-day default whenever the output is not a valid
date-time string, keeping all existing bats tests green without requiring
every test script to stub the new gh run list call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(collect-signals): align bats stub order with new gh run list call

The feed-checkpoint `gh run list` call added in the previous commit is
now the *first* gh invocation, so every manually-built stub script in
collect-signals.bats needs a corresponding first entry.

- Prepend run-list-last-success.txt to all 5 manual script builders
  (auth-failure, graphql-errors, bot-only-truncation,
  discussions-truncated, no-ideas-category)
- Fix date fallback format: append T00:00:00Z to date_days_ago output
  so the JSON Schema format:date-time constraint is satisfied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compose-signals.bats): update call sites to 12-arg signature

All compose_signals invocations now pass last_successful_run as
the new arg 10, shifting schema_version to 11 and
truncation_warnings to 12. Also adds last_successful_run to the
required-fields assertion in the empty-inputs test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): address CodeRabbit and Copilot review comments

- collect-signals.sh: use WORKFLOW_FILE env var (default: feature-ideation.yml)
  so repos that rename their caller stub can override without a code change;
  capture gh run list stderr in a temp file and log it when the fallback is
  triggered so auth/network failures are distinguishable from first-run
- feature-ideation-reusable.yml: clarify propagation comment — changes reach
  @v1 stubs only after the v1 tag is bumped, not on every next run
- ci-standards.md: align Tier-1 table wording with the @v1 tag-bump model
- standards/workflows/feature-ideation.yml: reword sources_file comment to
  make clear users must uncomment AND change the path for non-default locations;
  show a non-default example path to reduce ambiguity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add self-test feature-ideation stub for dry-run validation

* fix: trailing newline + clean up stub

* fix: pin reusable workflow ref to commit SHA (SonarCloud)

* chore: remove temporary test stub (not for main)

* fix(reusable): guard against empty sources_file in Phase 2 prompt

If a caller passes sources_file: '' the prompt previously rendered a
bare 'Read: ' instruction. Now uses a GitHub Actions expression to
branch: non-empty value emits the Read instruction; empty/omitted
emits a clear fallback note directing Mary to open web search and log
a warning in the step summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): move sources_file expression to env var to respect line-length

The format() expression was 241 chars, over the 200-char yamllint limit.
Moving it to SOURCES_INSTRUCTION in the step env block (where the
expression is still valid) and referencing $SOURCES_INSTRUCTION in the
prompt string brings all lines under 200 chars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): resolve YAML syntax error in sources_file prompt guard

The format() expression with backtick literals inside a GHA expression
caused a YAML mapping-value syntax error at parse time. Replaced with
a plain env var SOURCES_FILE_PATH + shell-style conditional in the prompt
text — no GHA expressions inside the multiline prompt string, fully
YAML-safe and under the 200-char line limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(dotgithub): add feature-ideation caller stub for .github self-test

Adds the Feature Research & Ideation workflow to the .github repo itself,
making it a BMAD-enabled consumer of its own reusable pipeline.

Key configuration:
- project_context: org-level DevX/tooling repo (CI standards, reusable
  workflows, BMAD framework, agent security)
- sources_file: 'standards/feature-ideation-sources.md' — the template
  lives right here, so no copy needed
- dry_run defaults to false (use workflow_dispatch input to enable)
- actions: read permission for feed checkpoint

Note: uses: SHA points to current v1. After this PR merges, bump the
v1 tag to the new merge commit and update the SHA here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
don-petry added a commit that referenced this pull request Jun 25, 2026
)

* feat(feature-ideation): per-repo source list + feed checkpoint via last successful run

Source list (addresses all Copilot/CodeRabbit/don-petry review threads):
- Add standards/feature-ideation-sources.md as a starter template; each
  adopting repo copies it to .github/feature-ideation-sources.md and owns
  it independently (no cross-repo checkout).
- Add sources_file input to the reusable workflow (default:
  .github/feature-ideation-sources.md). Phase 2 prompt reads the repo-
  local file; falls back to open web search if absent.
- Fix three arXiv RSS feed URLs from http:// to https://.
- Update propagation wording in ci-standards.md to reflect per-repo
  ownership and v1 tag model.
- Pin caller stub reusable ref from mutable @v1 to commit SHA ae9709f # v1.
- Add actions: read to gather-signals permissions and caller stub template
  (required for gh run list in same repo).

Feed checkpoint (new — avoids re-reviewing same content every week):
- collect-signals.sh: query gh run list --status=success --limit=1 to
  resolve the previous successful run timestamp; fall back to 30 days ago
  on first run or after a long outage.
- compose-signals.sh: add last_successful_run as arg 10 (schema_version
  shifts to arg 11, truncation_warnings to arg 12).
- signals.schema.json: add last_successful_run field; bump schema version
  1.0.0 → 1.1.0 (SCHEMA_VERSION constant updated in lockstep per bats test).
- Test fixtures (populated, empty-repo, truncated): add last_successful_run
  and bump schema_version to 1.1.0.
- Phase 2 prompt: instruct Mary to filter feed entries to those published
  after last_successful_run; bypass checkpoint if >60 days old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(feature-ideation): validate ISO-8601 format for last_successful_run fallback

The gh stub used in bats tests returns raw fixture JSON without applying
--jq filters, so the captured last_successful_run value was a JSON array
instead of an ISO-8601 timestamp. Add a grep -qE '^[0-9]{4}-...' guard
that falls back to the 30-day default whenever the output is not a valid
date-time string, keeping all existing bats tests green without requiring
every test script to stub the new gh run list call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(collect-signals): align bats stub order with new gh run list call

The feed-checkpoint `gh run list` call added in the previous commit is
now the *first* gh invocation, so every manually-built stub script in
collect-signals.bats needs a corresponding first entry.

- Prepend run-list-last-success.txt to all 5 manual script builders
  (auth-failure, graphql-errors, bot-only-truncation,
  discussions-truncated, no-ideas-category)
- Fix date fallback format: append T00:00:00Z to date_days_ago output
  so the JSON Schema format:date-time constraint is satisfied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compose-signals.bats): update call sites to 12-arg signature

All compose_signals invocations now pass last_successful_run as
the new arg 10, shifting schema_version to 11 and
truncation_warnings to 12. Also adds last_successful_run to the
required-fields assertion in the empty-inputs test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): address CodeRabbit and Copilot review comments

- collect-signals.sh: use WORKFLOW_FILE env var (default: feature-ideation.yml)
  so repos that rename their caller stub can override without a code change;
  capture gh run list stderr in a temp file and log it when the fallback is
  triggered so auth/network failures are distinguishable from first-run
- feature-ideation-reusable.yml: clarify propagation comment — changes reach
  @v1 stubs only after the v1 tag is bumped, not on every next run
- ci-standards.md: align Tier-1 table wording with the @v1 tag-bump model
- standards/workflows/feature-ideation.yml: reword sources_file comment to
  make clear users must uncomment AND change the path for non-default locations;
  show a non-default example path to reduce ambiguity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add self-test feature-ideation stub for dry-run validation

* fix: trailing newline + clean up stub

* fix: pin reusable workflow ref to commit SHA (SonarCloud)

* chore: remove temporary test stub (not for main)

* fix(reusable): guard against empty sources_file in Phase 2 prompt

If a caller passes sources_file: '' the prompt previously rendered a
bare 'Read: ' instruction. Now uses a GitHub Actions expression to
branch: non-empty value emits the Read instruction; empty/omitted
emits a clear fallback note directing Mary to open web search and log
a warning in the step summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): move sources_file expression to env var to respect line-length

The format() expression was 241 chars, over the 200-char yamllint limit.
Moving it to SOURCES_INSTRUCTION in the step env block (where the
expression is still valid) and referencing $SOURCES_INSTRUCTION in the
prompt string brings all lines under 200 chars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): resolve YAML syntax error in sources_file prompt guard

The format() expression with backtick literals inside a GHA expression
caused a YAML mapping-value syntax error at parse time. Replaced with
a plain env var SOURCES_FILE_PATH + shell-style conditional in the prompt
text — no GHA expressions inside the multiline prompt string, fully
YAML-safe and under the 200-char line limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(dotgithub): add feature-ideation caller stub for .github self-test

Adds the Feature Research & Ideation workflow to the .github repo itself,
making it a BMAD-enabled consumer of its own reusable pipeline.

Key configuration:
- project_context: org-level DevX/tooling repo (CI standards, reusable
  workflows, BMAD framework, agent security)
- sources_file: 'standards/feature-ideation-sources.md' — the template
  lives right here, so no copy needed
- dry_run defaults to false (use workflow_dispatch input to enable)
- actions: read permission for feed checkpoint

Note: uses: SHA points to current v1. After this PR merges, bump the
v1 tag to the new merge commit and update the SHA here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
don-petry added a commit that referenced this pull request Jun 25, 2026
)

* feat(feature-ideation): per-repo source list + feed checkpoint via last successful run

Source list (addresses all Copilot/CodeRabbit/don-petry review threads):
- Add standards/feature-ideation-sources.md as a starter template; each
  adopting repo copies it to .github/feature-ideation-sources.md and owns
  it independently (no cross-repo checkout).
- Add sources_file input to the reusable workflow (default:
  .github/feature-ideation-sources.md). Phase 2 prompt reads the repo-
  local file; falls back to open web search if absent.
- Fix three arXiv RSS feed URLs from http:// to https://.
- Update propagation wording in ci-standards.md to reflect per-repo
  ownership and v1 tag model.
- Pin caller stub reusable ref from mutable @v1 to commit SHA ae9709f # v1.
- Add actions: read to gather-signals permissions and caller stub template
  (required for gh run list in same repo).

Feed checkpoint (new — avoids re-reviewing same content every week):
- collect-signals.sh: query gh run list --status=success --limit=1 to
  resolve the previous successful run timestamp; fall back to 30 days ago
  on first run or after a long outage.
- compose-signals.sh: add last_successful_run as arg 10 (schema_version
  shifts to arg 11, truncation_warnings to arg 12).
- signals.schema.json: add last_successful_run field; bump schema version
  1.0.0 → 1.1.0 (SCHEMA_VERSION constant updated in lockstep per bats test).
- Test fixtures (populated, empty-repo, truncated): add last_successful_run
  and bump schema_version to 1.1.0.
- Phase 2 prompt: instruct Mary to filter feed entries to those published
  after last_successful_run; bypass checkpoint if >60 days old.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(feature-ideation): validate ISO-8601 format for last_successful_run fallback

The gh stub used in bats tests returns raw fixture JSON without applying
--jq filters, so the captured last_successful_run value was a JSON array
instead of an ISO-8601 timestamp. Add a grep -qE '^[0-9]{4}-...' guard
that falls back to the 30-day default whenever the output is not a valid
date-time string, keeping all existing bats tests green without requiring
every test script to stub the new gh run list call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(collect-signals): align bats stub order with new gh run list call

The feed-checkpoint `gh run list` call added in the previous commit is
now the *first* gh invocation, so every manually-built stub script in
collect-signals.bats needs a corresponding first entry.

- Prepend run-list-last-success.txt to all 5 manual script builders
  (auth-failure, graphql-errors, bot-only-truncation,
  discussions-truncated, no-ideas-category)
- Fix date fallback format: append T00:00:00Z to date_days_ago output
  so the JSON Schema format:date-time constraint is satisfied

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(compose-signals.bats): update call sites to 12-arg signature

All compose_signals invocations now pass last_successful_run as
the new arg 10, shifting schema_version to 11 and
truncation_warnings to 12. Also adds last_successful_run to the
required-fields assertion in the empty-inputs test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): address CodeRabbit and Copilot review comments

- collect-signals.sh: use WORKFLOW_FILE env var (default: feature-ideation.yml)
  so repos that rename their caller stub can override without a code change;
  capture gh run list stderr in a temp file and log it when the fallback is
  triggered so auth/network failures are distinguishable from first-run
- feature-ideation-reusable.yml: clarify propagation comment — changes reach
  @v1 stubs only after the v1 tag is bumped, not on every next run
- ci-standards.md: align Tier-1 table wording with the @v1 tag-bump model
- standards/workflows/feature-ideation.yml: reword sources_file comment to
  make clear users must uncomment AND change the path for non-default locations;
  show a non-default example path to reduce ambiguity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add self-test feature-ideation stub for dry-run validation

* fix: trailing newline + clean up stub

* fix: pin reusable workflow ref to commit SHA (SonarCloud)

* chore: remove temporary test stub (not for main)

* fix(reusable): guard against empty sources_file in Phase 2 prompt

If a caller passes sources_file: '' the prompt previously rendered a
bare 'Read: ' instruction. Now uses a GitHub Actions expression to
branch: non-empty value emits the Read instruction; empty/omitted
emits a clear fallback note directing Mary to open web search and log
a warning in the step summary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): move sources_file expression to env var to respect line-length

The format() expression was 241 chars, over the 200-char yamllint limit.
Moving it to SOURCES_INSTRUCTION in the step env block (where the
expression is still valid) and referencing $SOURCES_INSTRUCTION in the
prompt string brings all lines under 200 chars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lint): resolve YAML syntax error in sources_file prompt guard

The format() expression with backtick literals inside a GHA expression
caused a YAML mapping-value syntax error at parse time. Replaced with
a plain env var SOURCES_FILE_PATH + shell-style conditional in the prompt
text — no GHA expressions inside the multiline prompt string, fully
YAML-safe and under the 200-char line limit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(dotgithub): add feature-ideation caller stub for .github self-test

Adds the Feature Research & Ideation workflow to the .github repo itself,
making it a BMAD-enabled consumer of its own reusable pipeline.

Key configuration:
- project_context: org-level DevX/tooling repo (CI standards, reusable
  workflows, BMAD framework, agent security)
- sources_file: 'standards/feature-ideation-sources.md' — the template
  lives right here, so no copy needed
- dry_run defaults to false (use workflow_dispatch input to enable)
- actions: read permission for feed checkpoint

Note: uses: SHA points to current v1. After this PR merges, bump the
v1 tag to the new merge commit and update the SHA here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: DJ <dj@Rachels-Air.localdomain>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants