-
Notifications
You must be signed in to change notification settings - Fork 13
[AISOS-1883] Forge Workflow Statistics and Automated Reporting #100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
73 commits
Select commit
Hold shift + click to select a range
bfd5cbf
[AISOS-1888] Define StatsState mixin and StageStats TypedDict
ekuris-redhat 4e0974b
[AISOS-1889] Integrate StatsState mixin into FeatureState and BugState
ekuris-redhat 4922ace
[AISOS-1890] Implement core stats recording utility functions
ekuris-redhat 83f2b81
[AISOS-1891] Add cost alert threshold configuration
ekuris-redhat becb2df
[AISOS-1892] Define workflow stage constants for stats tracking
ekuris-redhat ab3e012
[AISOS-1893] Integrate stats recording into PRD and Spec generation n…
ekuris-redhat 93f3b49
[AISOS-1894] Implement Stats Summary Formatter Module
ekuris-redhat 42ea5f4
[AISOS-1895] Create Stats Comment Posting Service
ekuris-redhat 6c9a430
[AISOS-1896] Implement idempotency guard for stats comments
ekuris-redhat 575838a
[AISOS-1897] Implement re-post mechanism for final stats comment
ekuris-redhat 147d73e
[AISOS-1898] Create terminal event stats posting node
ekuris-redhat 63cef09
[AISOS-1899] Integrate stats posting into Feature and Bug workflow gr…
ekuris-redhat 8c81297
[AISOS-1900] Add cost alert posting to stats summary
ekuris-redhat 3b283e3
[AISOS-1901] Implement /forge stats Jira Comment Command Handler
ekuris-redhat 3bfc8df
[AISOS-1902] Implement /forge stats retry subcommand handler
ekuris-redhat 36c1a61
[AISOS-1903] Implement forge stats CLI command
ekuris-redhat d0286a5
[AISOS-1904] Create stats retrieval service module
ekuris-redhat d4c1077
[AISOS-1905] Add CLI stats formatter for terminal output
ekuris-redhat 12d1f2b
[AISOS-1906] Add integration tests for on-demand stats commands
ekuris-redhat 885c34f
[AISOS-1907] Implement Weekly Report Data Aggregation Module
ekuris-redhat 14d6a12
[AISOS-1908] Implement per-feature rollup aggregation for epic-linked…
ekuris-redhat e37ee5b
[AISOS-1909] Implement Weekly Report Formatters (CLI, Markdown, JSON)
ekuris-redhat 0e5371c
[AISOS-1910] Implement forge weekly-report CLI Command
ekuris-redhat 6d92fd6
[AISOS-1911] Implement Report Ticket Resolution and Auto-Creation
ekuris-redhat 58afae0
[AISOS-1912] Implement Jira-native notification delivery to project r…
ekuris-redhat c778fb2
[AISOS-1913] Add integration tests for weekly reporting system
ekuris-redhat 421f3ed
[AISOS-1883-review] Fix lint issues found during local code review
ekuris-redhat 62cb18b
[AISOS-1883-docs] docs: update documentation for /forge stats Jira co…
ekuris-redhat c4d5eff
[AISOS-1883-ci-fix] Fix Python 3.11 incompatibility in TypedDict inhe…
ekuris-redhat a16c29f
[AISOS-1883-rebase] Resolve merge conflicts with main for AISOS-1883
ekuris-redhat 076defc
[AISOS-1883-rebase] Resolve merge conflicts with main for AISOS-1883
ekuris-redhat 50376c2
[AISOS-1883-ci-fix] Remove feature-specific nodes from _TERMINAL_NODES
ekuris-redhat 57ae24e
[AISOS-1883] review: address PR feedback
ekuris-redhat a508126
[AISOS-1883-review-fix] Implement PR review plan for AISOS-1883
ekuris-redhat 02bc55b
[AISOS-1883-review-review-impl] Fix bug formatter stages and Redis by…
ekuris-redhat 8119240
[AISOS-1883-rebase] Resolve merge conflicts with main for AISOS-1883
ekuris-redhat 43b81d8
[AISOS-1883] review: address PR feedback
ekuris-redhat a6dc133
[AISOS-1883-review-review-impl] Fix incorrect keyword argument name i…
ekuris-redhat cb1ffad
Merge remote-tracking branch 'origin/main' into forge/aisos-1883
ekuris-redhat 9507f01
[AISOS-1883] review: address PR feedback
7af92a1
[AISOS-1883] review: address PR feedback
ekuris-redhat d4a61c6
[AISOS-1883-review-fix] Implement PR review plan for AISOS-1883
ekuris-redhat 73c8164
[AISOS-1883-ci-analyze] Analyze CI failures (attempt 1)
ekuris-redhat 6553a49
[AISOS-1883-ci-fix] Fix task generation unit test mock return values
ekuris-redhat 005a5c0
[AISOS-1883-review-ci-fix-1] Fix Mocking issues in PRD rejected tests
ekuris-redhat dc74954
[AISOS-1883] review: address PR feedback
ekuris-redhat c511b70
[AISOS-1883-review-review-impl] Post-review-impl code review and form…
ekuris-redhat dd93a2e
[AISOS-1883-review-review-impl] Post-review-impl code review and vali…
ekuris-redhat 674a844
[AISOS-1883-review-analyze] Analyze PR review feedback for AISOS-1883
ekuris-redhat 98b1bad
[AISOS-1883] review: address PR feedback
2151989
[AISOS-1883] review: address PR feedback
ekuris-redhat fea489c
[AISOS-1883-review-review-impl] Remove redundant sequential timing ca…
ekuris-redhat 58e45d0
[AISOS-1883] review: address PR feedback
ekuris-redhat abb7c96
[AISOS-1883-review-fix] review: address PR feedback
ekuris-redhat 5949782
[AISOS-1883-review-review-impl] Resolve all type-checking and type-sa…
ekuris-redhat 37291c2
[AISOS-1883-review-analyze] Analyze PR review feedback for AISOS-1883
ekuris-redhat fe8ab0d
[AISOS-1883] review: address PR feedback
ekuris-redhat 1cc78fb
[AISOS-1883-review-review-impl] Resolve remaining stats-related type-…
ekuris-redhat da09359
[AISOS-1883-review-review-impl] Post-review-impl code review and test…
ekuris-redhat bb9cb37
[AISOS-1883] review: address PR feedback
ekuris-redhat 35d6e94
[AISOS-1883-review-review-impl] Fix Redis connection errors in weekly…
ekuris-redhat 27e246e
[AISOS-1883] review: address PR feedback
ekuris-redhat 92936db
[AISOS-1883-review-review-impl] Post-review-impl code review fixes
ekuris-redhat 98349c4
[AISOS-1883] review: address PR feedback
ekuris-redhat f404d03
[AISOS-1883-review-review-impl] Post-review-impl code review and type…
ekuris-redhat 9291359
[AISOS-1883] review: address PR feedback
ekuris-redhat 74a2223
[AISOS-1883-review-review-impl] Post-review-impl code review
ekuris-redhat 6981331
[AISOS-1883] review: address PR feedback
ekuris-redhat 1fae412
[AISOS-1883] review: address PR feedback
ekuris-redhat 8ed5744
[AISOS-1883-review-review-impl] Fix breaking issues found in code rev…
ekuris-redhat c313d26
[AISOS-1883-review-fix] Revert formatting-only changes in test_ci_att…
ekuris-redhat 0eb8412
Merge remote-tracking branch 'origin/main' into forge/aisos-1883
ekuris-redhat 4740972
[AISOS-1883] review: address PR feedback
ekuris-redhat File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -42,6 +42,7 @@ ENV/ | |
|
|
||
| # Testing | ||
| .pytest_cache/ | ||
| .mypy_cache/ | ||
| .coverage | ||
| htmlcov/ | ||
| *.cover | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| # Weekly Reporting System | ||
|
|
||
| Forge includes an automated, weekly aggregation and reporting system that compiles and publishes metrics across all managed tickets for a specific Jira project. This documentation explains how the reporting system operates behind the scenes. | ||
|
|
||
| ## Quick Start | ||
|
|
||
| Generate a weekly report for your project (e.g., `PROJ`) with the following command: | ||
|
|
||
| ```bash | ||
| forge weekly-report --project PROJ | ||
| ``` | ||
|
|
||
| > **Note:** The `forge weekly-report` command requires active Redis access and must be run from the Forge project directory containing `.env` to load configurations. | ||
|
|
||
| ## Aggregation Logic | ||
|
|
||
| When you run `forge weekly-report` (or trigger it via automated schedules), the reporting system performs the following steps: | ||
|
|
||
| 1. **Query Active/Historical Checkpoints:** Forge scans the Redis event and state checkpoints for the specified project (`PROJECT_KEY`). It uses a key scanning pattern `checkpoint:{PROJECT_KEY}-*` to find all state checkpoints. | ||
| 2. **Filter by Sliding Window:** Metrics are collected and filtered based on a sliding window of `N` days (by default, `7` days). A checkpoint falls within the reporting window if its `updated_at` timestamp or any stage `started_at`/`ended_at` timestamp is greater than or equal to the cutoff (`now - N days`). | ||
| 3. **Aggregate Stats per Stage:** Data is aggregated across all feature and bug workflows, tracking: | ||
| - **Ticket Rollups:** Total numbers of active, completed, or blocked workflows. | ||
| - **Machine Time:** Cumulative active machine processing time (monotonic durations) across all stages. | ||
| - **LLM Token Costs:** Sum of all input and output tokens consumed, translating them into actual dollar costs based on LLM pricing mappings. | ||
| - **Feature Rollups:** Metrics aggregated per epic-linked ticket and feature. Ancestry traversal resolves the parent/grandparent Feature for each ticket in Jira up to two hops (e.g., ticket -> Epic -> Feature). Tickets without a resolved Feature are grouped under the "Unassigned" bucket. | ||
| - **Bottleneck Analysis:** Identifies the slowest stage by average duration, ranks stages by iteration count, and calculates the CI fix rate. | ||
|
|
||
| ## Idempotency & Ticket Publishing | ||
|
|
||
| To avoid cluttering Jira with duplicate reports every week, the reporting system is designed to be completely **idempotent** when publishing to Jira via the `--create-ticket` flag. | ||
|
|
||
| - **Ticket Naming Convention:** The ticket summary is formatted dynamically based on the project key and current date: | ||
| ```text | ||
| Forge Weekly Report - {PROJECT} - Week of {date} | ||
| ``` | ||
| Where `{PROJECT}` is the project key, and `{date}` is the first day of the reporting week (i.e. `today - N + 1 days`). | ||
| - **Label Identification:** The system uses the special `forge:weekly-report` and `forge:generated` labels to identify and tag report tickets. | ||
| - **Idempotency Guard:** | ||
| - When `--create-ticket` is run, Forge first searches Jira using the following JQL: | ||
| ```jql | ||
| project = "{PROJECT}" AND labels = "forge:weekly-report" AND summary ~ "Week of {date}" | ||
| ``` | ||
| - If a matching ticket is found, Forge updates that existing ticket's description with the newly compiled statistics instead of creating a new one. | ||
| - If no matching ticket exists, Forge creates a new Jira Task issue, assigns the `forge:weekly-report` and `forge:generated` labels, and sets the description. | ||
|
|
||
| ## Stakeholder Notifications | ||
|
|
||
| When using the `--notify` option alongside `--create-ticket`, Forge automatically mentions and notifies designated stakeholders. | ||
|
|
||
| ### Notification List Compilation | ||
|
|
||
| The notification list is compiled hierarchically to allow easy overriding (highest priority first): | ||
|
|
||
| 1. **Jira Project Property (Highest Priority):** Forge attempts to read the `forge.weekly-report.notify` project property from Jira. This property must contain a JSON array of Jira Account IDs (e.g., `["account-id-1", "account-id-2"]`) or a comma-separated string of account IDs. | ||
| 2. **Environment Variable (Global Fallback):** If no project-specific property is set, Forge falls back to the `FORGE_WEEKLY_REPORT_NOTIFY` environment variable in `.env`. This variable should contain a comma-separated list of Jira Account IDs or the keyword `"project-leads"`. The special value `"project-leads"` instructs Forge to query the per-project Jira property. | ||
| 3. **No Recipients:** If neither is configured, no notifications are triggered. | ||
|
|
||
| ### How Notifications are Delivered | ||
|
|
||
| Once the recipient account IDs are resolved: | ||
| - Forge posts a comment directly on the generated weekly report Jira ticket. | ||
| - The comment mentions each stakeholder using Jira's native `[~accountid:{id}]` mention syntax. | ||
| - This triggers email and/or Slack notifications based on the users' individual Atlassian notification preferences, ensuring visibility to project leads and management. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to clarify our intentions to support stats. 1) Will we support stats if users do not configure langfuse or another supported LLM observability tool? If the answer is yes, metrics gathering in agent containers is compulsory. 2) Either way, manual token accounting increases complexity and risk of langfuse drifting from the manually counted metrics. We should consider what it would look like to gather the same token data directly from langfuse and weigh its added complexity against the manual account in metrics.json.