@plainconceptsplatform/workflows 0.4.33 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/README.md +88 -88
  2. package/loops/actions/agent-output.cjs +17 -17
  3. package/loops/actions/audit-close/action.yml +24 -0
  4. package/loops/actions/classify-route/action.yml +4 -3
  5. package/loops/actions/classify-route/classify-route.sh +69 -29
  6. package/loops/actions/load-issue-context/action.yml +2 -0
  7. package/loops/actions/update-changelog/action.yml +113 -0
  8. package/loops/actions/validate-merge-gate-output/action.yml +40 -0
  9. package/loops/actions/validate-merge-gate-output/validate-merge-gate-output.sh +34 -0
  10. package/loops/actions/validate-refine-output/validate-refine-output.sh +16 -3
  11. package/loops/actions/validate-review-output/action.yml +35 -0
  12. package/loops/actions/validate-review-output/validate-review-output.sh +30 -0
  13. package/loops/actions/validate-triage-output/action.yml +36 -0
  14. package/loops/actions/validate-triage-output/validate-triage-output.sh +36 -0
  15. package/loops/actions/verify-route-matrix/verify-route-matrix.sh +121 -36
  16. package/loops/scripts/compile-agent-workflows.mjs +195 -6
  17. package/loops/templates/agentics/agentics-checks.yml +86 -86
  18. package/loops/templates/agentics/agentics-maintenance.yml +121 -121
  19. package/loops/templates/ci/app-ci-dotnet-next.yml +268 -171
  20. package/loops/templates/ci/app-ci-node-monorepo.yml +208 -178
  21. package/loops/templates/issues/bug_report.yml +109 -109
  22. package/loops/templates/issues/feature_request.yml +75 -75
  23. package/loops/templates/opencode/opencode.ci.json +49 -47
  24. package/loops/templates/opencode/opencode.ci.json.md +46 -41
  25. package/loops/templates/release/github-release.yml +30 -30
  26. package/loops/workflows/agent-apply-review.md +465 -373
  27. package/loops/workflows/agent-audit.md +213 -197
  28. package/loops/workflows/agent-implement.md +538 -374
  29. package/loops/workflows/agent-merge-gate.md +730 -485
  30. package/loops/workflows/agent-refine.md +609 -379
  31. package/loops/workflows/agent-release.md +258 -0
  32. package/loops/workflows/agent-triage.md +447 -0
  33. package/loops/workflows/authorize-bot-work.yml +85 -81
  34. package/loops/workflows/shared/opencode-ci.md +206 -197
  35. package/loops/workflows/shared/platform-defaults.md +19 -16
  36. package/loops/workflows/work-router.yml +862 -551
  37. package/package.json +42 -42
  38. package/dist/catalog-installation.d.ts +0 -30
  39. package/dist/catalog-installation.js +0 -352
  40. package/dist/catalog-installation.test.d.ts +0 -1
  41. package/dist/catalog-installation.test.js +0 -448
  42. package/dist/catalog-listing.d.ts +0 -13
  43. package/dist/catalog-listing.js +0 -70
  44. package/dist/catalog-listing.test.d.ts +0 -1
  45. package/dist/catalog-listing.test.js +0 -150
  46. package/dist/index.d.ts +0 -2
  47. package/dist/index.js +0 -218
  48. package/dist/index.test.d.ts +0 -1
  49. package/dist/index.test.js +0 -273
  50. package/dist/repository-inspection.d.ts +0 -23
  51. package/dist/repository-inspection.js +0 -113
  52. package/dist/repository-inspection.test.d.ts +0 -1
  53. package/dist/repository-inspection.test.js +0 -77
  54. package/dist/repository-state.d.ts +0 -18
  55. package/dist/repository-state.js +0 -77
  56. package/dist/repository-state.test.d.ts +0 -1
  57. package/dist/repository-state.test.js +0 -96
  58. package/dist/route-processing.d.ts +0 -6
  59. package/dist/route-processing.js +0 -150
  60. package/dist/route-processing.test.d.ts +0 -1
  61. package/dist/route-processing.test.js +0 -342
  62. package/dist/stack-defaults.d.ts +0 -11
  63. package/dist/stack-defaults.js +0 -104
  64. package/dist/stack-defaults.test.d.ts +0 -1
  65. package/dist/stack-defaults.test.js +0 -266
  66. package/dist/tui.d.ts +0 -25
  67. package/dist/tui.js +0 -287
  68. package/dist/tui.test.d.ts +0 -1
  69. package/dist/tui.test.js +0 -246
  70. package/dist/workflow-catalog.d.ts +0 -25
  71. package/dist/workflow-catalog.js +0 -57
  72. package/dist/workflow-catalog.test.d.ts +0 -1
  73. package/dist/workflow-catalog.test.js +0 -29
  74. package/loops/workflows/agent-direct.md +0 -363
  75. package/loops/workflows/agent-propose.md +0 -342
@@ -1,197 +1,213 @@
1
- ---
2
- # Managed by @plainconceptsplatform/workflows. Source: loops/workflows/agent-audit.md. Update with `workflows update --force`; consumer edits may be overwritten.
3
- env:
4
- REPO_RULES: "Read-only repository audit. Report only reproducible, actionable defects with evidence. Look for: architectural layer violations, missing tests, security gaps, performance issues, and documentation drift. Do not modify files, commit, push, or run write operations."
5
- AUDIT_MARKER: "<!-- agent-audit -->"
6
- GIT_AUTHOR_NAME: "github-actions[bot]"
7
- GIT_AUTHOR_EMAIL: "github-actions[bot]@users.noreply.github.com"
8
- GIT_COMMITTER_NAME: "github-actions[bot]"
9
- GIT_COMMITTER_EMAIL: "github-actions[bot]@users.noreply.github.com"
10
- description: |
11
- Read-only repository audit. Finds 5-7 problems, scores each 1-10, files a single issue
12
- with all findings listed and the top 3 refined as actionable user stories. The issue is
13
- labelled `audit` + `bug` + `implement`. Replaces .loops/recipes/guardrails-audit-loop.yaml.
14
-
15
- Router-only worker: triggered exclusively via workflow_call from work-router.yml.
16
- Contract input: trigger-kind(scheduled|manual).
17
- The router owns the weekly Monday schedule and manual dispatch.
18
-
19
- The `skip-if-match` below is backpressure, so the audit stops filing reports while three
20
- are still unactioned.
21
-
22
- name: "Agent: Audit"
23
-
24
- # Shared: network policy only. This workflow owns its Safe Outputs and OpenCode configuration.
25
- # permissions, engine, model and runs-on cannot be shared , see shared/platform-defaults.md.
26
- imports:
27
- - github/gh-aw/.github/workflows/shared/opencode.md@v0.86.2
28
- - shared/platform-defaults.md
29
- - shared/opencode-ci.md
30
-
31
- on:
32
- workflow_call:
33
- inputs:
34
- trigger-kind:
35
- description: "Audit trigger: scheduled or manual"
36
- required: false
37
- type: string
38
- default: manual
39
-
40
- # Rung 1. Do not pile reports on top of unactioned reports.
41
- skip-if-match:
42
- query: "is:issue is:open label:audit"
43
- max: 3
44
-
45
- runs-on: RunnerLandingZone
46
- runs-on-slim: RunnerLandingZone
47
-
48
- secrets:
49
- OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
50
-
51
- engine:
52
- id: opencode
53
- version: "1.2.14"
54
- env:
55
- OPENAI_BASE_URL: https://forge.plainconcepts.com/v1
56
-
57
- model: openai/glm-5-2
58
-
59
- max-turns: 300
60
- max-turn-cache-misses: 3000
61
- max-ai-credits: 5000
62
-
63
- permissions: read-all
64
-
65
- steps:
66
- - name: List what is already tracked
67
- uses: ./.github/actions/list-open-issues
68
- with:
69
- token: ${{ github.token }}
70
- repo: ${{ github.repository }}
71
-
72
- jobs:
73
- conclude:
74
- needs: [activation, agent, safe_outputs]
75
- if: >
76
- needs.agent.result == 'success' &&
77
- needs.safe_outputs.result == 'success' &&
78
- needs.safe_outputs.outputs.process_safe_outputs_processed_count != '0'
79
- runs-on: RunnerLandingZone
80
- permissions:
81
- contents: read
82
- issues: write
83
- steps:
84
- - name: Checkout workflow actions
85
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
86
- with:
87
- persist-credentials: false
88
- - name: Create bot token
89
- id: app-token
90
- uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
91
- with:
92
- client-id: ${{ secrets.BOT_APP_ID }}
93
- private-key: ${{ secrets.BOT_PRIVATE_KEY }}
94
- - name: Apply agent output
95
- id: agent-output
96
- uses: ./.github/actions/apply-agent-output
97
- with:
98
- artifact-name: ${{ needs.activation.outputs.artifact_prefix }}agent
99
- token: ${{ steps.app-token.outputs.token }}
100
- create-issues: 'true'
101
- - name: Apply audit labels to created issues
102
- if: steps.agent-output.outputs.first-issue-number != ''
103
- uses: ./.github/actions/add-issue-labels
104
- with:
105
- token: ${{ steps.app-token.outputs.token }}
106
- issue-number: ${{ steps.agent-output.outputs.first-issue-number }}
107
- labels: |
108
- audit
109
- bug
110
- implement
111
-
112
- safe-outputs:
113
- staged: true
114
- threat-detection: false
115
- create-issue:
116
- max: 1
117
- add-comment:
118
-
119
-
120
- timeout-minutes: 45
121
- ---
122
-
123
- 1. Call skill("ob-repo-audit"), then run `/repo-audit` as a read-only audit of this
124
- repository. Do not modify any file, do not commit, and do not push.
125
-
126
- 2. Apply repository documentation and established conventions while auditing. Focus on
127
- concrete defects and avoid recommendations that weaken security, tests, or checks.
128
- Adhere to ${{ env.REPO_RULES }}.
129
-
130
- From the audit report, find **5 to 7 problems**. For each finding, verify it meets ALL
131
- of these criteria before keeping it:
132
- - A specific, reproducible problem in a specific file or component.
133
- - Has real impact: security risk, data loss, crash, or broken functionality.
134
- - Something a developer could pick up and fix without further investigation.
135
- Discard anything vague, stylistic, theoretical, or nice-to-have. If you cannot find 5 that
136
- meet this bar, file as many as you can. If you find zero, call `noop` and stop , that is a
137
- good result.
138
-
139
- 3. **Score each surviving finding from 1 to 10**, based on:
140
- | Factor | Weight |
141
- |---|---|
142
- | Severity (how bad is the impact?) | high |
143
- | Likelihood (how often does it trigger?) | medium |
144
- | Blast radius (how many users/components affected?) | medium |
145
- | Ease of fix (can it be fixed in one PR?) | low bonus |
146
-
147
- Write the score next to each finding in your reasoning.
148
-
149
- 4. Read `/tmp/gh-aw/agent/open-issues.json`, which lists every open issue with its title and
150
- labels. Discard any finding already tracked there. Exact-title duplicates are rejected for
151
- you; your job is the ones worded differently that mean the same thing.
152
-
153
- 5. Call `create_issue` **once** with title "Audit: <date>". Do NOT specify labels , the
154
- conclude job will apply them. The body MUST have two sections:
155
-
156
- **Section 1 , All findings:** A numbered list of every finding (5-7) with its score,
157
- file path, and a one-line description. Order by score descending.
158
-
159
- **Section 2 , Top 3 to implement:** Call skill("ob-plan-story") and refine the top 3
160
- findings by score into user stories in Mike Cohn's As a / I want to / so that format
161
- with Given/When/Then acceptance criteria, edge cases, and likely files to change. Mark
162
- this section clearly with a heading like `## Top 3 , To Implement`.
163
-
164
- 6. If nothing met the bar, call `noop` and stop. Filing nothing is the right outcome when
165
- the codebase is clean.
166
-
167
- ## Diagram
168
-
169
- ```mermaid
170
- flowchart TD
171
- auditStart("Work Router<br/>audit route<br/>(Mondays or dispatch)") --> auditBackpressure
172
- auditBackpressure["Backpressure (rung 1)<br/>Fewer than 3 open reports?"] -->|✓| auditTracked
173
- auditBackpressure -.->|✗| auditIdle
174
- auditTracked("Tracked (rung 3)<br/>Open issue titles to disk") --> auditRun
175
- auditRun("Audit<br/>/repo-audit, read-only") -->|✓| auditTriage
176
- auditRun -.->|✗| auditFail
177
- auditTriage["Triage<br/>Find 5-7 problems, score 1-10, dedupe"] -->|✓| auditPropose
178
- auditTriage -.->|nothing found| auditQuiet
179
- auditPropose("Propose<br/>Single issue: all findings + top 3 refined") -->|✓| auditReport
180
- auditPropose -.->|✗| auditFail
181
- auditReport(("Conclude<br/>audit+bug+implement on single issue"))
182
- auditQuiet(("Quiet<br/>Nothing actionable, nothing proposed"))
183
- auditIdle(("Idle<br/>Reports still awaiting action"))
184
- auditFail(("Fail<br/>Audit or proposal failed"))
185
- classDef start fill:#ffffff,stroke:#172033,stroke-width:2px,color:#172033
186
- classDef action fill:#eef0ff,stroke:#554cff,stroke-width:2px,color:#172033
187
- classDef decision fill:#fff8e8,stroke:#c75b00,stroke-width:2px,color:#172033
188
- classDef idle fill:#202c40,stroke:#738198,stroke-width:2px,color:#ffffff
189
- classDef failure fill:#fff0f0,stroke:#ef2929,stroke-width:2px,color:#8b1a2a
190
- classDef success fill:#e8f8ec,stroke:#18883c,stroke-width:2px,color:#145a32
191
- class auditStart start
192
- class auditTracked,auditRun,auditPropose action
193
- class auditBackpressure,auditTriage decision
194
- class auditQuiet,auditIdle idle
195
- class auditFail failure
196
- class auditReport success
197
- ```
1
+ ---
2
+ # Managed by @plainconceptsplatform/workflows. Source: loops/workflows/agent-audit.md. Update with `workflows update --force`; consumer edits may be overwritten.
3
+ env:
4
+ REPO_RULES: "Read-only repository audit. Report only reproducible, actionable defects with evidence. Look for: architectural layer violations, missing tests, security gaps, performance issues, and documentation drift. Do not modify files, commit, push, or run write operations."
5
+ AUDIT_MARKER: "<!-- agent-audit -->"
6
+ GIT_AUTHOR_NAME: "github-actions[bot]"
7
+ GIT_AUTHOR_EMAIL: "github-actions[bot]@users.noreply.github.com"
8
+ GIT_COMMITTER_NAME: "github-actions[bot]"
9
+ GIT_COMMITTER_EMAIL: "github-actions[bot]@users.noreply.github.com"
10
+ description: |
11
+ Read-only repository audit. Finds 5-7 problems, scores each 1-10, files a single issue
12
+ with all findings listed and the top 3 refined as actionable user stories. The issue is
13
+ labelled `audit` + `bug` + `refine`, so Refine sizes it and splits a multi-defect report
14
+ into one estimated issue per finding rather than one pull request that has to fix them all. Replaces .loops/recipes/guardrails-audit-loop.yaml.
15
+
16
+ Router-only worker: triggered exclusively via workflow_call from work-router.yml.
17
+ Contract input: trigger-kind(scheduled|manual).
18
+ The router owns the weekly Monday schedule and manual dispatch.
19
+
20
+ The `skip-if-match` below is backpressure, so the audit stops filing reports while three
21
+ are still unactioned.
22
+
23
+ name: "Agent: Audit"
24
+
25
+ # Shared: network policy only. This workflow owns its Safe Outputs and OpenCode configuration.
26
+ # permissions, engine, model and runs-on cannot be shared , see shared/platform-defaults.md.
27
+ imports:
28
+ - github/gh-aw/.github/workflows/shared/opencode.md@v0.87.5
29
+ - shared/platform-defaults.md
30
+ - shared/opencode-ci.md
31
+
32
+ on:
33
+ workflow_call:
34
+ inputs:
35
+ trigger-kind:
36
+ description: "Audit trigger: scheduled or manual"
37
+ required: false
38
+ type: string
39
+ default: manual
40
+
41
+ # Rung 1. Do not pile reports on top of unactioned reports.
42
+ skip-if-match:
43
+ query: "is:issue is:open label:audit"
44
+ max: 3
45
+
46
+ runs-on: agents-arc
47
+ runs-on-slim: agents-arc
48
+
49
+ secrets:
50
+ OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
51
+
52
+ engine:
53
+ id: opencode
54
+ version: "1.2.14"
55
+ env:
56
+ OPENAI_BASE_URL: https://forge.plainconcepts.com/v1
57
+
58
+ model: openai/glm-5-3
59
+
60
+ max-turns: 300
61
+ max-turn-cache-misses: 3000
62
+ max-ai-credits: 5000
63
+
64
+ permissions: read-all
65
+
66
+ steps:
67
+ - name: List what is already tracked
68
+ uses: ./.github/actions/list-open-issues
69
+ with:
70
+ token: ${{ github.token }}
71
+ repo: ${{ github.repository }}
72
+
73
+ jobs:
74
+ conclude:
75
+ needs: [activation, agent, safe_outputs]
76
+ if: >
77
+ needs.agent.result == 'success' &&
78
+ needs.safe_outputs.result == 'success' &&
79
+ needs.safe_outputs.outputs.process_safe_outputs_processed_count != '0'
80
+ runs-on: agents-arc
81
+ permissions:
82
+ contents: read
83
+ issues: write
84
+ steps:
85
+ - name: Checkout workflow actions
86
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
87
+ with:
88
+ persist-credentials: false
89
+ - name: Create bot token
90
+ id: app-token
91
+ uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
92
+ with:
93
+ client-id: ${{ secrets.BOT_APP_ID }}
94
+ private-key: ${{ secrets.BOT_PRIVATE_KEY }}
95
+ # No apply-agent-output here. The safe_outputs job already created the issue and
96
+ # exposes its number; calling the action with create-issues would file a second copy
97
+ # of the same report. It was only needed while staged: true suppressed the native
98
+ # write, and staged is gone.
99
+ - name: Apply audit labels to created issues
100
+ if: needs.safe_outputs.outputs.created_issue_number != ''
101
+ uses: ./.github/actions/add-issue-labels
102
+ with:
103
+ token: ${{ steps.app-token.outputs.token }}
104
+ issue-number: ${{ needs.safe_outputs.outputs.created_issue_number }}
105
+ labels: |
106
+ audit
107
+ bug
108
+ refine
109
+
110
+ safe-outputs:
111
+ # A failed run is already a red run. An issue per failure buries the real backlog
112
+ # under noise nobody closes.
113
+ report-failure-as-issue: false
114
+ threat-detection: false
115
+ create-issue:
116
+ max: 1
117
+
118
+ timeout-minutes: 45
119
+ ---
120
+
121
+ 1. Call skill("pc-repo-audit"), then run `/repo-audit` as a read-only audit of this
122
+ repository. Do not modify any file, do not commit, and do not push.
123
+
124
+ 2. Apply repository documentation and established conventions while auditing. Focus on
125
+ concrete defects and avoid recommendations that weaken security, tests, or checks.
126
+ Adhere to ${{ env.REPO_RULES }}.
127
+
128
+ From the audit report, find **5 to 7 problems**. For each finding, verify it meets ALL
129
+ of these criteria before keeping it:
130
+ - A specific, reproducible problem in a specific file or component.
131
+ - Has real impact: security risk, data loss, crash, or broken functionality.
132
+ - Something a developer could pick up and fix without further investigation.
133
+ Discard anything vague, stylistic, theoretical, or nice-to-have. If you cannot find 5 that
134
+ meet this bar, file as many as you can. If you find zero, call `noop` and stop , that is a
135
+ good result.
136
+
137
+ 3. **Score each surviving finding from 1 to 10**, based on:
138
+ | Factor | Weight |
139
+ |---|---|
140
+ | Severity (how bad is the impact?) | high |
141
+ | Likelihood (how often does it trigger?) | medium |
142
+ | Blast radius (how many users/components affected?) | medium |
143
+ | Ease of fix (can it be fixed in one PR?) | low bonus |
144
+
145
+ Write the score next to each finding in your reasoning.
146
+
147
+ 4. Read `/tmp/gh-aw/agent/open-issues.json`, which lists every open issue with its title and
148
+ labels. Discard any finding already tracked there. Exact-title duplicates are rejected for
149
+ you; your job is the ones worded differently that mean the same thing.
150
+
151
+ Open issues only cover what is still open, so a finding reported weeks ago and closed
152
+ without a fix, or deliberately rejected, would come back every single run. Before scoring,
153
+ call `memory_smart_search` for prior audits of this repository and drop any finding that
154
+ was already reported and consciously not acted on. After you have decided what to file,
155
+ call `memory_save` once with a compact record of this audit: the date, each finding's file
156
+ and one-line description, and its disposition (filed, already tracked, or previously
157
+ rejected). Keep it short; it is read by the next audit, not by a person.
158
+
159
+ A finding you have reported before and that is genuinely still broken IS worth filing
160
+ again. What this prevents is re-filing something the team looked at and chose to live
161
+ with, which is the noise that makes an audit backlog get ignored.
162
+
163
+ 5. Call `create_issue` **once** with title "Audit: <date>". Do NOT specify labels , the
164
+ conclude job will apply them. The body MUST have two sections:
165
+
166
+ **Section 1 , All findings:** A numbered list of every finding (5-7) with its score,
167
+ file path, and a one-line description. Order by score descending.
168
+
169
+ **Section 2 , Top 3 to implement:** Call skill("pc-plan-story") and refine the top 3
170
+ findings by score into user stories in Mike Cohn's As a / I want to / so that format
171
+ with Given/When/Then acceptance criteria, edge cases, and likely files to change. Mark
172
+ this section clearly with a heading like `## Top 3 , To Implement`.
173
+
174
+ The issue you file goes to Refine, not straight to implementation. Refine sizes it and,
175
+ because a report of several unrelated defects across different files is exactly the shape
176
+ that does not land as one pull request, splits it into one properly estimated issue per
177
+ finding. Write each finding so it survives that split: self-contained, naming its own
178
+ files and its own acceptance criteria, never "as above" or "same as finding 2".
179
+
180
+ 6. If nothing met the bar, call `noop` and stop. Filing nothing is the right outcome when
181
+ the codebase is clean.
182
+
183
+ ## Diagram
184
+
185
+ ```mermaid
186
+ flowchart TD
187
+ auditStart("Work Router<br/>audit route<br/>(Mondays or dispatch)") --> auditBackpressure
188
+ auditBackpressure["Backpressure (rung 1)<br/>Fewer than 3 open reports?"] -->|✓| auditTracked
189
+ auditBackpressure -.->|✗| auditIdle
190
+ auditTracked("Tracked (rung 3)<br/>Open issue titles to disk") --> auditRun
191
+ auditRun("Audit<br/>/repo-audit, read-only") -->|✓| auditTriage
192
+ auditRun -.->|✗| auditFail
193
+ auditTriage["Triage<br/>Find 5-7 problems, score 1-10, dedupe"] -->|✓| auditPropose
194
+ auditTriage -.->|nothing found| auditQuiet
195
+ auditPropose("Propose<br/>Single issue: all findings + top 3 refined") -->|✓| auditReport
196
+ auditPropose -.->|✗| auditFail
197
+ auditReport(("Conclude<br/>audit+bug+refine on single issue<br/>Refine sizes and splits it"))
198
+ auditQuiet(("Quiet<br/>Nothing actionable, nothing proposed"))
199
+ auditIdle(("Idle<br/>Reports still awaiting action"))
200
+ auditFail(("Fail<br/>Audit or proposal failed"))
201
+ classDef start fill:#ffffff,stroke:#172033,stroke-width:2px,color:#172033
202
+ classDef action fill:#eef0ff,stroke:#554cff,stroke-width:2px,color:#172033
203
+ classDef decision fill:#fff8e8,stroke:#c75b00,stroke-width:2px,color:#172033
204
+ classDef idle fill:#202c40,stroke:#738198,stroke-width:2px,color:#ffffff
205
+ classDef failure fill:#fff0f0,stroke:#ef2929,stroke-width:2px,color:#8b1a2a
206
+ classDef success fill:#e8f8ec,stroke:#18883c,stroke-width:2px,color:#145a32
207
+ class auditStart start
208
+ class auditTracked,auditRun,auditPropose action
209
+ class auditBackpressure,auditTriage decision
210
+ class auditQuiet,auditIdle idle
211
+ class auditFail failure
212
+ class auditReport success
213
+ ```