@plainconceptsplatform/workflows 0.1.2 → 0.2.0

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 (71) hide show
  1. package/README.md +40 -11
  2. package/dist/catalog-installation.d.ts +11 -2
  3. package/dist/catalog-installation.js +53 -9
  4. package/dist/catalog-installation.test.js +198 -16
  5. package/dist/catalog-listing.d.ts +13 -0
  6. package/dist/catalog-listing.js +68 -0
  7. package/dist/catalog-listing.test.d.ts +1 -0
  8. package/dist/catalog-listing.test.js +137 -0
  9. package/dist/index.js +76 -12
  10. package/dist/index.test.d.ts +1 -0
  11. package/dist/index.test.js +112 -0
  12. package/dist/repository-inspection.test.d.ts +1 -0
  13. package/dist/repository-inspection.test.js +77 -0
  14. package/dist/tui.d.ts +25 -0
  15. package/dist/tui.js +254 -0
  16. package/dist/tui.test.d.ts +1 -0
  17. package/dist/tui.test.js +246 -0
  18. package/dist/workflow-catalog.d.ts +15 -8
  19. package/dist/workflow-catalog.js +25 -15
  20. package/dist/workflow-catalog.test.js +18 -3
  21. package/loops/actions/add-issue-labels/action.yml +30 -29
  22. package/loops/actions/agent-output.cjs +1 -0
  23. package/loops/actions/apply-agent-bundle/action.yml +24 -23
  24. package/loops/actions/apply-agent-bundle/apply-bundle.sh +1 -0
  25. package/loops/actions/apply-agent-comments/action.yml +42 -41
  26. package/loops/actions/apply-agent-labels/action.yml +55 -54
  27. package/loops/actions/apply-agent-output/action.yml +108 -107
  28. package/loops/actions/audit-close/action.yml +104 -103
  29. package/loops/actions/classify-route/action.yml +91 -90
  30. package/loops/actions/classify-route/classify-route.sh +1 -0
  31. package/loops/actions/cleanup-artifacts/action.yml +65 -64
  32. package/loops/actions/close-agent-issues/action.yml +43 -42
  33. package/loops/actions/create-agent-issues/action.yml +52 -51
  34. package/loops/actions/create-issue-comment/action.yml +29 -28
  35. package/loops/actions/download-agent-output/action.yml +53 -52
  36. package/loops/actions/identify-gate-subject/action.yml +97 -96
  37. package/loops/actions/link-pr-to-issue/action.yml +40 -39
  38. package/loops/actions/list-open-issues/action.yml +33 -32
  39. package/loops/actions/load-issue-context/action.yml +43 -42
  40. package/loops/actions/merge-agent-pr/action.yml +36 -35
  41. package/loops/actions/push-agent-branch/action.yml +45 -44
  42. package/loops/actions/remove-issue-labels/action.yml +35 -34
  43. package/loops/actions/stale-recovery/action.yml +288 -287
  44. package/loops/actions/update-agent-issues/action.yml +58 -57
  45. package/loops/actions/validate-refine-output/action.yml +44 -43
  46. package/loops/actions/validate-refine-output/validate-refine-output.sh +1 -0
  47. package/loops/actions/verify-composite-actions/action.yml +9 -8
  48. package/loops/actions/verify-composite-actions/verify-composite-actions.sh +1 -0
  49. package/loops/actions/verify-refine-output/action.yml +9 -8
  50. package/loops/actions/verify-refine-output/verify-refine-output.sh +1 -0
  51. package/loops/actions/verify-route-matrix/action.yml +9 -8
  52. package/loops/actions/verify-route-matrix/verify-route-matrix.sh +1 -0
  53. package/loops/scripts/compile-agent-workflows.mjs +29 -13
  54. package/loops/templates/agentics/agentics-checks.yml +86 -0
  55. package/loops/templates/agentics/agentics-maintenance.yml +121 -0
  56. package/loops/templates/ci/app-ci-dotnet-next.yml +167 -0
  57. package/loops/templates/ci/app-ci-node-monorepo.yml +178 -0
  58. package/loops/templates/opencode/opencode.ci.json +46 -0
  59. package/loops/templates/opencode/opencode.ci.json.md +41 -0
  60. package/loops/workflows/agent-apply-review.md +9 -10
  61. package/loops/workflows/agent-audit.md +6 -7
  62. package/loops/workflows/agent-direct.md +7 -8
  63. package/loops/workflows/agent-implement.md +7 -8
  64. package/loops/workflows/agent-merge-gate.md +9 -10
  65. package/loops/workflows/agent-propose.md +7 -8
  66. package/loops/workflows/agent-refine.md +5 -7
  67. package/loops/workflows/shared/opencode-ci.md +105 -1
  68. package/loops/workflows/shared/platform-defaults.md +1 -0
  69. package/loops/workflows/work-router.yml +1 -0
  70. package/package.json +2 -2
  71. package/loops/aw/repo-config.md +0 -12
@@ -0,0 +1,167 @@
1
+ # Managed by @plainconceptsplatform/workflows. Source: loops/templates/ci/app-ci-dotnet-next.yml. Update with `workflows update --force`; consumer edits may be overwritten.
2
+ name: "App: CI (.NET + Next.js)"
3
+
4
+ on:
5
+ pull_request:
6
+ schedule:
7
+ - cron: "0 6 * * 1"
8
+ workflow_dispatch:
9
+
10
+ env:
11
+ DOTNET_VERSION: "10.0.x"
12
+ NODE_VERSION: "22"
13
+ PNPM_VERSION: "10"
14
+ API_WORKING_DIRECTORY: apps/api
15
+ DOTNET_SOLUTION: Numa.slnx
16
+ UNIT_TEST_PROJECT: tests/Numa.UnitTests/Numa.UnitTests.csproj
17
+ PARITY_TEST_PROJECT: tests/Numa.ParityTests/Numa.ParityTests.csproj
18
+ INTEGRATION_TEST_PROJECT: tests/Numa.IntegrationTests/Numa.IntegrationTests.csproj
19
+ COVERAGE_SETTINGS: coverage.runsettings
20
+ COVERAGE_CHECK_COMMAND: node ../../scripts/check-coverage.mjs TestResults/merged/Cobertura.xml
21
+ MIGRATION_PROJECT: src/Numa.Infrastructure/Numa.Infrastructure.csproj
22
+ MIGRATION_STARTUP_PROJECT: src/Numa.Api/Numa.Api.csproj
23
+ SEED_PROJECT: src/Numa.Seed
24
+ PRIMARY_DATABASE: numa
25
+ DATA_LAYER_DATABASE: numa_dl
26
+ SQL_SA_PASSWORD: "YourStrong!Passw0rd"
27
+ SQL_PORT: "1433"
28
+ WEB_PACKAGE: "@numa/web"
29
+ NPM_REGISTRY_URL: "//npm.pkg.github.com/"
30
+ TRUFFLEHOG_IMAGE: "trufflesecurity/trufflehog:latest"
31
+ SEMGREP_IMAGE: "semgrep/semgrep:1.168.0"
32
+ SBOM_ARTIFACT_NAME: numa-sbom.cyclonedx.json
33
+ MIGRATION_CONTEXT: NumaDbContext
34
+
35
+ permissions:
36
+ contents: read
37
+
38
+ concurrency:
39
+ group: ci-${{ github.workflow }}-${{ github.head_ref || github.ref }}
40
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
41
+
42
+ jobs:
43
+ api:
44
+ name: API (.NET)
45
+ if: github.event_name != 'schedule'
46
+ runs-on: ubuntu-latest
47
+ timeout-minutes: 30
48
+ services:
49
+ sqlserver:
50
+ image: mcr.microsoft.com/mssql/server:2022-latest
51
+ env:
52
+ ACCEPT_EULA: "Y"
53
+ MSSQL_SA_PASSWORD: ${{ env.SQL_SA_PASSWORD }}
54
+ ports:
55
+ - ${{ env.SQL_PORT }}:1433
56
+ options: >-
57
+ --health-cmd "/opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P '${{ env.SQL_SA_PASSWORD }}' -Q 'SELECT 1' -C || exit 1"
58
+ --health-interval 10s --health-timeout 5s --health-retries 12 --health-start-period 30s
59
+ defaults:
60
+ run:
61
+ working-directory: ${{ env.API_WORKING_DIRECTORY }}
62
+ steps:
63
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
64
+ - uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6
65
+ with:
66
+ dotnet-version: ${{ env.DOTNET_VERSION }}
67
+ - name: Restore tools, solution, and build
68
+ run: |
69
+ dotnet tool restore
70
+ dotnet restore "$DOTNET_SOLUTION"
71
+ dotnet build "$DOTNET_SOLUTION" --no-restore -c Release
72
+ - name: Unit tests with coverage
73
+ run: dotnet test "$UNIT_TEST_PROJECT" --no-build -c Release --collect:"XPlat Code Coverage" --settings "$COVERAGE_SETTINGS" --results-directory TestResults
74
+ - name: Parity tests
75
+ run: dotnet test "$PARITY_TEST_PROJECT" --no-build -c Release
76
+ - name: Create test databases
77
+ run: |
78
+ for database in "$PRIMARY_DATABASE" "$DATA_LAYER_DATABASE"; do
79
+ docker exec ${{ job.services.sqlserver.id }} /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "$SQL_SA_PASSWORD" -C -Q "IF DB_ID('$database') IS NULL CREATE DATABASE [$database];"
80
+ done
81
+ - name: Apply migrations and seed test data
82
+ env:
83
+ ConnectionStrings__Numa: Server=localhost,${{ env.SQL_PORT }};Database=${{ env.PRIMARY_DATABASE }};User Id=sa;Password=${{ env.SQL_SA_PASSWORD }};TrustServerCertificate=true
84
+ DataLayer__ConnectionString: Server=localhost,${{ env.SQL_PORT }};Database=${{ env.DATA_LAYER_DATABASE }};User Id=sa;Password=${{ env.SQL_SA_PASSWORD }};TrustServerCertificate=true
85
+ DATALAYER_SEED: "true"
86
+ run: |
87
+ dotnet ef database update -p "$MIGRATION_PROJECT" -s "$MIGRATION_STARTUP_PROJECT" --context "$MIGRATION_CONTEXT"
88
+ dotnet run --project "$SEED_PROJECT" --no-build -c Release
89
+ - name: Integration tests with coverage
90
+ env:
91
+ ConnectionStrings__Numa: Server=localhost,${{ env.SQL_PORT }};Database=${{ env.PRIMARY_DATABASE }};User Id=sa;Password=${{ env.SQL_SA_PASSWORD }};TrustServerCertificate=true
92
+ DataLayer__ConnectionString: Server=localhost,${{ env.SQL_PORT }};Database=${{ env.DATA_LAYER_DATABASE }};User Id=sa;Password=${{ env.SQL_SA_PASSWORD }};TrustServerCertificate=true
93
+ run: dotnet test "$INTEGRATION_TEST_PROJECT" --no-build -c Release --collect:"XPlat Code Coverage" --settings "$COVERAGE_SETTINGS" --results-directory TestResults
94
+ - name: Enforce merged coverage floor
95
+ run: |
96
+ dotnet tool install --global dotnet-reportgenerator-globaltool
97
+ reportgenerator -reports:"TestResults/**/coverage.cobertura.xml" -targetdir:TestResults/merged -reporttypes:Cobertura
98
+ bash -c "$COVERAGE_CHECK_COMMAND"
99
+
100
+ web:
101
+ name: Web (Next.js)
102
+ if: github.event_name != 'schedule'
103
+ runs-on: ubuntu-latest
104
+ timeout-minutes: 15
105
+ steps:
106
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
107
+ - uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4
108
+ with:
109
+ version: ${{ env.PNPM_VERSION }}
110
+ run_install: false
111
+ - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
112
+ with:
113
+ node-version: ${{ env.NODE_VERSION }}
114
+ cache: pnpm
115
+ cache-dependency-path: pnpm-lock.yaml
116
+ - name: Configure optional private registry authentication
117
+ env:
118
+ NPM_REGISTRY_TOKEN: ${{ secrets.NPM_REGISTRY_TOKEN }}
119
+ run: |
120
+ if [ -n "$NPM_REGISTRY_TOKEN" ]; then
121
+ echo "${NPM_REGISTRY_URL}:_authToken=$NPM_REGISTRY_TOKEN" >> .npmrc
122
+ fi
123
+ - run: pnpm install --frozen-lockfile
124
+ - name: Lint, test, verify boundaries, and build
125
+ run: |
126
+ pnpm --filter "$WEB_PACKAGE" run lint
127
+ pnpm --filter "$WEB_PACKAGE" run test
128
+ pnpm --filter "$WEB_PACKAGE" run lint:fsd
129
+ pnpm --filter "$WEB_PACKAGE" run build
130
+
131
+ secret-scan:
132
+ name: Secret scan (TruffleHog)
133
+ runs-on: ubuntu-latest
134
+ steps:
135
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
136
+ - run: docker run --rm -v "${{ github.workspace }}:/repo" "$TRUFFLEHOG_IMAGE" filesystem /repo --only-verified --fail --no-update
137
+
138
+ deps-and-iac-scan:
139
+ name: Dependencies and IaC (Trivy)
140
+ runs-on: ubuntu-latest
141
+ steps:
142
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
143
+ - uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
144
+ with:
145
+ scan-type: fs
146
+ scanners: vuln,misconfig,secret
147
+ severity: CRITICAL,HIGH
148
+ ignore-unfixed: true
149
+ exit-code: "1"
150
+ format: table
151
+
152
+ sast-scan:
153
+ name: SAST (Semgrep)
154
+ runs-on: ubuntu-latest
155
+ steps:
156
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
157
+ - run: docker run --rm -v "${{ github.workspace }}:/src" -w /src "$SEMGREP_IMAGE" semgrep scan --error --metrics=off --oss-only --disable-version-check --config p/default --config p/security-audit --config p/secrets --config p/csharp --config p/typescript --config p/react --exclude-rule yaml.github-actions.security.github-actions-mutable-action-tag.github-actions-mutable-action-tag
158
+
159
+ sbom:
160
+ name: SBOM (CycloneDX)
161
+ runs-on: ubuntu-latest
162
+ steps:
163
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
164
+ - uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0
165
+ with:
166
+ format: cyclonedx-json
167
+ artifact-name: ${{ env.SBOM_ARTIFACT_NAME }}
@@ -0,0 +1,178 @@
1
+ # Managed by @plainconceptsplatform/workflows. Source: loops/templates/ci/app-ci-node-monorepo.yml. Update with `workflows update --force`; consumer edits may be overwritten.
2
+ name: "App: CI (Node monorepo)"
3
+
4
+ on:
5
+ pull_request:
6
+ schedule:
7
+ - cron: "0 6 * * 1"
8
+ workflow_dispatch:
9
+
10
+ env:
11
+ NODE_VERSION: "22"
12
+ PNPM_VERSION: "10"
13
+ WEB_PACKAGE: "@orbion/web"
14
+ DESKTOP_PACKAGE: "@orbion/desktop"
15
+ MOBILE_PACKAGE: "@orbion/mobile"
16
+ WEB_EXPORT_PATH: apps/web/out
17
+ PLAYWRIGHT_REPORT_PATH: apps/web/playwright-report
18
+ DESKTOP_MAIN_PATH: apps/desktop/out/main/index.js
19
+ DESKTOP_PRELOAD_PATH: apps/desktop/out/preload/index.cjs
20
+ DESKTOP_PRELOAD_BRIDGE_PATTERN: exposeInMainWorld
21
+ MOBILE_IOS_PATH: apps/mobile/ios
22
+ MOBILE_ANDROID_PATH: apps/mobile/android
23
+ WEB_ARTIFACT_NAME: web-export
24
+ PLAYWRIGHT_ARTIFACT_NAME: playwright-report
25
+ TRUFFLEHOG_IMAGE: "trufflesecurity/trufflehog:latest"
26
+ SEMGREP_IMAGE: "semgrep/semgrep:1.168.0"
27
+ SBOM_ARTIFACT_NAME: orbion-sbom.cyclonedx.json
28
+
29
+ permissions:
30
+ contents: read
31
+
32
+ concurrency:
33
+ group: ci-${{ github.workflow }}-${{ github.head_ref || github.ref }}
34
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
35
+
36
+ jobs:
37
+ lint:
38
+ name: Lint (Biome)
39
+ if: github.event_name != 'schedule'
40
+ runs-on: ubuntu-latest
41
+ steps:
42
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
43
+ - uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4
44
+ with: { version: ${{ env.PNPM_VERSION }}, run_install: false }
45
+ - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
46
+ with: { node-version: ${{ env.NODE_VERSION }}, cache: pnpm }
47
+ - run: pnpm install --frozen-lockfile
48
+ - run: pnpm exec biome check .
49
+
50
+ web:
51
+ name: Web (Next.js static export)
52
+ if: github.event_name != 'schedule'
53
+ runs-on: ubuntu-latest
54
+ steps:
55
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
56
+ - uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4
57
+ with: { version: ${{ env.PNPM_VERSION }}, run_install: false }
58
+ - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
59
+ with: { node-version: ${{ env.NODE_VERSION }}, cache: pnpm }
60
+ - run: pnpm install --frozen-lockfile
61
+ - run: pnpm --filter "$WEB_PACKAGE" run typecheck
62
+ - run: pnpm --filter "$WEB_PACKAGE" run test
63
+ - run: pnpm --filter "$WEB_PACKAGE" run lint:fsd
64
+ - run: pnpm --filter "$WEB_PACKAGE" run build
65
+ - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
66
+ with:
67
+ name: ${{ env.WEB_ARTIFACT_NAME }}
68
+ path: ${{ env.WEB_EXPORT_PATH }}
69
+ retention-days: 3
70
+ if-no-files-found: error
71
+
72
+ e2e:
73
+ name: E2E (Playwright)
74
+ if: github.event_name != 'schedule'
75
+ needs: web
76
+ runs-on: ubuntu-latest
77
+ steps:
78
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
79
+ - uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4
80
+ with: { version: ${{ env.PNPM_VERSION }}, run_install: false }
81
+ - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
82
+ with: { node-version: ${{ env.NODE_VERSION }}, cache: pnpm }
83
+ - run: pnpm install --frozen-lockfile
84
+ - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
85
+ with:
86
+ name: ${{ env.WEB_ARTIFACT_NAME }}
87
+ path: ${{ env.WEB_EXPORT_PATH }}
88
+ - run: pnpm --filter "$WEB_PACKAGE" exec playwright install --with-deps chromium webkit
89
+ - run: pnpm --filter "$WEB_PACKAGE" run e2e
90
+ - if: failure()
91
+ uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
92
+ with:
93
+ name: ${{ env.PLAYWRIGHT_ARTIFACT_NAME }}
94
+ path: ${{ env.PLAYWRIGHT_REPORT_PATH }}
95
+ retention-days: 7
96
+
97
+ desktop:
98
+ name: Desktop (Electron)
99
+ if: github.event_name != 'schedule'
100
+ needs: web
101
+ runs-on: ubuntu-latest
102
+ steps:
103
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
104
+ - uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4
105
+ with: { version: ${{ env.PNPM_VERSION }}, run_install: false }
106
+ - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
107
+ with: { node-version: ${{ env.NODE_VERSION }}, cache: pnpm }
108
+ - run: pnpm install --frozen-lockfile
109
+ - run: pnpm --filter "$DESKTOP_PACKAGE" run typecheck
110
+ - run: pnpm --filter "$DESKTOP_PACKAGE" run build
111
+ - run: |
112
+ test -f "$DESKTOP_MAIN_PATH"
113
+ test -f "$DESKTOP_PRELOAD_PATH"
114
+ grep -q "$DESKTOP_PRELOAD_BRIDGE_PATTERN" "$DESKTOP_PRELOAD_PATH"
115
+ - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
116
+ with:
117
+ name: ${{ env.WEB_ARTIFACT_NAME }}
118
+ path: ${{ env.WEB_EXPORT_PATH }}
119
+ - run: pnpm --filter "$DESKTOP_PACKAGE" exec playwright install-deps chromium
120
+ - run: xvfb-run --auto-servernum pnpm --filter "$DESKTOP_PACKAGE" run e2e
121
+
122
+ mobile:
123
+ name: Mobile (Capacitor)
124
+ if: github.event_name != 'schedule'
125
+ runs-on: ubuntu-latest
126
+ steps:
127
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
128
+ - uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4
129
+ with: { version: ${{ env.PNPM_VERSION }}, run_install: false }
130
+ - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
131
+ with: { node-version: ${{ env.NODE_VERSION }}, cache: pnpm }
132
+ - run: pnpm install --frozen-lockfile
133
+ - run: pnpm --filter "$MOBILE_PACKAGE" run typecheck
134
+ - run: |
135
+ if [ -d "$MOBILE_IOS_PATH" ] || [ -d "$MOBILE_ANDROID_PATH" ]; then
136
+ pnpm --filter "$WEB_PACKAGE" run build
137
+ pnpm --filter "$MOBILE_PACKAGE" run sync
138
+ else
139
+ echo "::notice::Native projects absent; skipping Capacitor sync."
140
+ fi
141
+
142
+ secret-scan:
143
+ name: Secret scan (TruffleHog)
144
+ runs-on: ubuntu-latest
145
+ steps:
146
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
147
+ - run: docker run --rm -v "${{ github.workspace }}:/repo" "$TRUFFLEHOG_IMAGE" filesystem /repo --only-verified --fail --no-update
148
+
149
+ deps-and-iac-scan:
150
+ name: Dependencies and IaC (Trivy)
151
+ runs-on: ubuntu-latest
152
+ steps:
153
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
154
+ - uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
155
+ with:
156
+ scan-type: fs
157
+ scanners: vuln,misconfig,secret
158
+ severity: CRITICAL,HIGH
159
+ ignore-unfixed: true
160
+ exit-code: "1"
161
+ format: table
162
+
163
+ sast-scan:
164
+ name: SAST (Semgrep)
165
+ runs-on: ubuntu-latest
166
+ steps:
167
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
168
+ - run: docker run --rm -v "${{ github.workspace }}:/src" -w /src "$SEMGREP_IMAGE" semgrep scan --error --metrics=off --oss-only --disable-version-check --config p/default --config p/security-audit --config p/secrets --config p/typescript --config p/react --exclude-rule yaml.github-actions.security.github-actions-mutable-action-tag.github-actions-mutable-action-tag
169
+
170
+ sbom:
171
+ name: SBOM (CycloneDX)
172
+ runs-on: ubuntu-latest
173
+ steps:
174
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
175
+ - uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0
176
+ with:
177
+ format: cyclonedx-json
178
+ artifact-name: ${{ env.SBOM_ARTIFACT_NAME }}
@@ -0,0 +1,46 @@
1
+ {
2
+ "$schema": "https://opencode.ai/config.json",
3
+ "model": "plainconcepts/glm-5-2",
4
+ "plugin": [],
5
+ "default_agent": "ci-workflow-agent",
6
+ "agent": {
7
+ "ci-workflow-agent": {
8
+ "description": "Executes GitHub Agentic Workflow tasks in CI.",
9
+ "mode": "primary",
10
+ "prompt": "You execute the GitHub Agentic Workflow task in the user prompt. Read AGENTS.md before any non-trivial change. Load only skills the workflow task explicitly names via skill(); when a workflow says load @skill-name, call skill(\"skill-name\"), the @ prefix is just a hint to use the skill tool. Execute only the requested task and required commands. Do not probe or inspect unrelated commands. The GitHub CLI is intentionally unauthenticated: never use `gh` for GitHub reads or writes. Read supplied workflow files first, then use the GitHub MCP tools only when fresh GitHub data is required. Use direct `safeoutputs` commands for GitHub writes. For syntax-only validation of a conventional GitHub Actions YAML file, use Ruby's standard YAML library; do not probe, install, or fall back through PyYAML, js-yaml, actionlint, or Docker. A task is complete only after every required Safe Outputs command succeeds. After the final required Safe Outputs command, stop immediately without further tools, prose, or model turns. Use `mcpscripts` only when the runtime explicitly lists it as available.\n\nOUTPUT DISCIPLINE: Do not narrate. Do not explain what you are about to do before doing it. Do not write prose between tool calls. Call tools silently. The only prose you produce is the final result or a brief error explanation when something fails. Never output sentences like 'Let me check...', 'Now I will...', 'I have enough context...', or 'Next I need to...'. If you are about to call a tool, just call it. If you must think, use the todowrite tool, not prose."
11
+ }
12
+ },
13
+ "permission": {
14
+ "read": "allow",
15
+ "external_directory": {
16
+ "/tmp/**": "allow"
17
+ }
18
+ },
19
+ "lsp": {
20
+ "csharp": {
21
+ "disabled": true
22
+ },
23
+ "fsharp": {
24
+ "disabled": true
25
+ },
26
+ "razor": {
27
+ "disabled": true
28
+ }
29
+ },
30
+ "provider": {
31
+ "plainconcepts": {
32
+ "api": "http://172.30.0.30:10000",
33
+ "options": {
34
+ "apiKey": "awf-openai-proxy"
35
+ },
36
+ "models": {
37
+ "glm-5-2": {
38
+ "name": "GLM 5.2"
39
+ },
40
+ "glm-5-1": {
41
+ "name": "GLM 5.1"
42
+ }
43
+ }
44
+ }
45
+ }
46
+ }
@@ -0,0 +1,41 @@
1
+ # Ownership: opencode.ci.json
2
+
3
+ Managed by @plainconceptsplatform/workflows. Source:
4
+ `loops/templates/opencode/opencode.ci.json`. Update with
5
+ `workflows update --force --template opencode.ci.json`; consumer edits may be
6
+ overwritten.
7
+
8
+ JSON (RFC 8259) does not permit comments, so the ownership header is documented
9
+ here instead of inline in `opencode.ci.json`.
10
+
11
+ ## Template contents
12
+
13
+ This template provides a standalone OpenCode CI configuration for consumer
14
+ repositories running agentic workflows in GitHub Actions. It is copied to the
15
+ repository root as `opencode.ci.json`.
16
+
17
+ ### Provider
18
+
19
+ - **plainconcepts** at `http://172.30.0.30:10000` with apiKey `awf-openai-proxy`.
20
+ - Two models registered: `glm-5-2` ("GLM 5.2") and `glm-5-1` ("GLM 5.1").
21
+ - Default model: `plainconcepts/glm-5-2`.
22
+
23
+ ### Agent
24
+
25
+ - **ci-workflow-agent** in `primary` mode with the output discipline directive:
26
+ no narration, no prose between tool calls, stop immediately after the final
27
+ Safe Outputs command.
28
+
29
+ ### LSP
30
+
31
+ - `csharp`, `fsharp`, and `razor` LSP servers are disabled. Consumers not
32
+ working with .NET can remove the `lsp` block entirely.
33
+
34
+ ### Consumer edits
35
+
36
+ After copying, edit the file directly for repository-specific needs:
37
+
38
+ - Change the model or add providers.
39
+ - Adjust agent prompt rules or permissions.
40
+ - Remove the `lsp` block if LSP is not needed or add other language servers.
41
+ - Add MCP servers or plugins as required.
@@ -1,5 +1,8 @@
1
1
  ---
2
+ # Managed by @plainconceptsplatform/workflows. Source: loops/workflows/agent-apply-review.md. Update with `workflows update --force`; consumer edits may be overwritten.
2
3
  env:
4
+ REPO_RULES: "Apply only actionable outstanding reviewer feedback to selected bot pull request. Preserve accepted behavior and scope; verify with pnpm verify; do not refactor unrelated code."
5
+ OPENAI_BASE_URL: https://forge.plainconcepts.com/v1
3
6
  WORKING_LABEL: bot-working
4
7
  REVIEW_LABEL: review
5
8
  REVIEW_MARKER: "<!-- agent-apply-review -->"
@@ -23,7 +26,6 @@ name: "Agent: Apply Review"
23
26
  imports:
24
27
  - shared/platform-defaults.md
25
28
  - shared/opencode-ci.md
26
- - shared/repo-config.md
27
29
 
28
30
  on:
29
31
  workflow_call:
@@ -220,7 +222,7 @@ engine:
220
222
  id: opencode
221
223
  version: "1.2.14"
222
224
  env:
223
- OPENAI_BASE_URL: https://forge.plainconcepts.com/v1
225
+ OPENAI_BASE_URL: ${{ env.OPENAI_BASE_URL }}
224
226
 
225
227
  model: openai/glm-5-2
226
228
 
@@ -312,19 +314,16 @@ timeout-minutes: 45
312
314
 
313
315
  5. Load only skills required by the feedback, then apply it. Make only changes the feedback
314
316
  justifies: a review comment is not licence for unrelated refactoring. Never read outside this
315
- repository root. Follow these repository-specific rules:
316
-
317
- ```
318
- ${{ env.REPO_RULES }}
319
- ```
317
+ repository root. Follow repository documentation and established conventions. Keep changes
318
+ focused, protect secrets, and do not modify generated files unless the feedback requires it.
320
319
 
321
320
  6. Run the repository verification commands below. The issue context at
322
321
  `${{ env.ISSUE_CONTEXT_PATH }}` defines acceptance criteria the fix must satisfy. If a check
323
322
  fails, fix what you broke and run it again. Do not push a branch that does not pass.
324
323
 
325
- ```
326
- ${{ env.VERIFY_COMMANDS }}
327
- ```
324
+ ```
325
+ pnpm verify
326
+ ```
328
327
 
329
328
  7. Call `push_to_pull_request_branch` to push the verified changes. Do not merge, do not
330
329
  close anything, and do not change any label other than `bot-working`.
@@ -1,5 +1,8 @@
1
1
  ---
2
+ # Managed by @plainconceptsplatform/workflows. Source: loops/workflows/agent-audit.md. Update with `workflows update --force`; consumer edits may be overwritten.
2
3
  env:
4
+ REPO_RULES: "Read-only audit. Report only reproducible, actionable defects with evidence; do not modify files, commit, push, or recommend weakened security, tests, or checks."
5
+ OPENAI_BASE_URL: https://forge.plainconcepts.com/v1
3
6
  AUDIT_MARKER: "<!-- agent-audit -->"
4
7
  GIT_AUTHOR_NAME: "github-actions[bot]"
5
8
  GIT_AUTHOR_EMAIL: "github-actions[bot]@users.noreply.github.com"
@@ -24,7 +27,6 @@ name: "Agent: Audit"
24
27
  imports:
25
28
  - shared/platform-defaults.md
26
29
  - shared/opencode-ci.md
27
- - shared/repo-config.md
28
30
 
29
31
  on:
30
32
  workflow_call:
@@ -50,7 +52,7 @@ engine:
50
52
  id: opencode
51
53
  version: "1.2.14"
52
54
  env:
53
- OPENAI_BASE_URL: https://forge.plainconcepts.com/v1
55
+ OPENAI_BASE_URL: ${{ env.OPENAI_BASE_URL }}
54
56
 
55
57
  model: openai/glm-5-2
56
58
 
@@ -121,11 +123,8 @@ timeout-minutes: 45
121
123
  1. Call skill("ob-repo-audit"), then run `/repo-audit` as a read-only audit of this
122
124
  repository. Do not modify any file, do not commit, and do not push.
123
125
 
124
- 2. Apply these repository-specific rules while auditing:
125
-
126
- ```
127
- ${{ env.REPO_RULES }}
128
- ```
126
+ 2. Apply repository documentation and established conventions while auditing. Focus on
127
+ concrete defects and avoid recommendations that weaken security, tests, or checks.
129
128
 
130
129
  From the audit report, find **5 to 7 problems**. For each finding, verify it meets ALL
131
130
  of these criteria before keeping it:
@@ -1,5 +1,8 @@
1
1
  ---
2
+ # Managed by @plainconceptsplatform/workflows. Source: loops/workflows/agent-direct.md. Update with `workflows update --force`; consumer edits may be overwritten.
2
3
  env:
4
+ REPO_RULES: "Execute selected issue's latest human instruction. Keep scope to requested outcome; follow repository documentation and conventions; verify code changes with pnpm verify; choose documented safe-output outcome."
5
+ OPENAI_BASE_URL: https://forge.plainconcepts.com/v1
3
6
  WORKING_LABEL: bot-working
4
7
  REVIEW_LABEL: review
5
8
  DIRECT_LABEL: direct
@@ -25,7 +28,6 @@ name: "Agent: Direct"
25
28
  imports:
26
29
  - shared/platform-defaults.md
27
30
  - shared/opencode-ci.md
28
- - shared/repo-config.md
29
31
 
30
32
  on:
31
33
  workflow_call:
@@ -186,7 +188,7 @@ engine:
186
188
  id: opencode
187
189
  version: "1.2.14"
188
190
  env:
189
- OPENAI_BASE_URL: https://forge.plainconcepts.com/v1
191
+ OPENAI_BASE_URL: ${{ env.OPENAI_BASE_URL }}
190
192
 
191
193
  model: openai/glm-5-2
192
194
 
@@ -275,14 +277,11 @@ timeout-minutes: 180
275
277
  6. Verify before you conclude, if you changed code. From the repository root:
276
278
 
277
279
  ```
278
- ${{ env.VERIFY_COMMANDS }}
280
+ pnpm verify
279
281
  ```
280
282
 
281
- Follow these repository-specific rules:
282
-
283
- ```
284
- ${{ env.REPO_RULES }}
285
- ```
283
+ Follow repository documentation and established conventions. Keep changes focused,
284
+ protect secrets, do not bypass checks, and do not modify generated files unless the instruction requires it.
286
285
 
287
286
  If a check fails, fix the cause and rerun. Do not weaken a test, lower a threshold, or skip
288
287
  a check to make it pass.
@@ -1,5 +1,8 @@
1
1
  ---
2
+ # Managed by @plainconceptsplatform/workflows. Source: loops/workflows/agent-implement.md. Update with `workflows update --force`; consumer edits may be overwritten.
2
3
  env:
4
+ REPO_RULES: "Implement only selected issue. Follow repository documentation and existing conventions; run pnpm verify; fix root cause; do not weaken checks or change unrelated files."
5
+ OPENAI_BASE_URL: https://forge.plainconcepts.com/v1
3
6
  IMPLEMENT_LABEL: implement
4
7
  WORKING_LABEL: bot-working
5
8
  REVIEW_LABEL: review
@@ -28,7 +31,6 @@ name: "Agent: Implement Issue"
28
31
  imports:
29
32
  - shared/platform-defaults.md
30
33
  - shared/opencode-ci.md
31
- - shared/repo-config.md
32
34
 
33
35
  on:
34
36
  workflow_call:
@@ -190,7 +192,7 @@ engine:
190
192
  id: opencode
191
193
  version: "1.2.14"
192
194
  env:
193
- OPENAI_BASE_URL: https://forge.plainconcepts.com/v1
195
+ OPENAI_BASE_URL: ${{ env.OPENAI_BASE_URL }}
194
196
 
195
197
  model: openai/glm-5-2
196
198
 
@@ -250,16 +252,13 @@ timeout-minutes: 90
250
252
  `${{ env.ISSUE_CONTEXT_PATH }}` defines acceptance criteria that the pipeline must
251
253
  satisfy.
252
254
 
253
- e. Follow these repository-specific rules:
254
-
255
- ```
256
- ${{ env.REPO_RULES }}
257
- ```
255
+ e. Follow repository documentation and established conventions. Keep changes focused,
256
+ protect secrets, do not bypass checks, and do not modify generated files unless the issue requires it.
258
257
 
259
258
  4. Verify before you conclude. From the repository root:
260
259
 
261
260
  ```
262
- ${{ env.VERIFY_COMMANDS }}
261
+ pnpm verify
263
262
  ```
264
263
 
265
264
  If a check fails, fix the cause and rerun. Do not weaken a test, lower a threshold, or skip
@@ -1,5 +1,8 @@
1
1
  ---
2
+ # Managed by @plainconceptsplatform/workflows. Source: loops/workflows/agent-merge-gate.md. Update with `workflows update --force`; consumer edits may be overwritten.
2
3
  env:
4
+ REPO_RULES: "Make risk-based decision for selected bot pull request. Merge only clean successful CI; flag security, API, workflow, protected-file, test, scope, or confidence risks; remediate only failed CI root cause and verify."
5
+ OPENAI_BASE_URL: https://forge.plainconcepts.com/v1
3
6
  WORKING_LABEL: bot-working
4
7
  IMPLEMENT_LABEL: implement
5
8
  REVIEW_LABEL: review
@@ -25,7 +28,6 @@ name: "Agent: Merge Gate"
25
28
  imports:
26
29
  - shared/platform-defaults.md
27
30
  - shared/opencode-ci.md
28
- - shared/repo-config.md
29
31
 
30
32
  on:
31
33
  workflow_call:
@@ -287,7 +289,7 @@ engine:
287
289
  id: opencode
288
290
  version: "1.2.14"
289
291
  env:
290
- OPENAI_BASE_URL: https://forge.plainconcepts.com/v1
292
+ OPENAI_BASE_URL: ${{ env.OPENAI_BASE_URL }}
291
293
 
292
294
  model: openai/glm-5-2
293
295
 
@@ -375,11 +377,8 @@ timeout-minutes: 60
375
377
  then `add_labels` to add `review` (item_number: the issue), and stop.
376
378
  A cancelled or unknown run is not evidence of anything.
377
379
 
378
- Apply these repository-specific rules when assessing or remediating the pull request:
379
-
380
- ```
381
- ${{ env.REPO_RULES }}
382
- ```
380
+ Follow repository documentation and established conventions when assessing or remediating
381
+ the pull request. Protect secrets, do not bypass checks, and keep remediation focused.
383
382
 
384
383
  4. Assess the risk of merging, as a reviewer would. Read `/tmp/gh-aw/agent/diff.patch` in full
385
384
  and `/tmp/gh-aw/agent/pr.json` for the shape of the change. Flag it as risky when any of
@@ -415,9 +414,9 @@ timeout-minutes: 60
415
414
  fix the actual cause. Run these verification commands before a push. Do not weaken a test,
416
415
  disable a check, or push an unverified guess.
417
416
 
418
- ```
419
- ${{ env.VERIFY_COMMANDS }}
420
- ```
417
+ ```
418
+ pnpm verify
419
+ ```
421
420
 
422
421
  Call `push_to_pull_request_branch` (pr_number: ${{ needs.subject.outputs.pr }}) to push
423
422
  the fix, then `remove_labels` (item_number: ${{ needs.subject.outputs.issue }}) to remove