@xn-intenton-z2a/agentic-lib 7.4.31 → 7.4.33

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.
@@ -19,7 +19,7 @@ on:
19
19
  mode:
20
20
  type: string
21
21
  required: false
22
- default: "update"
22
+ default: "purge"
23
23
  dry-run:
24
24
  type: string
25
25
  required: false
@@ -27,7 +27,7 @@ on:
27
27
  mission-seed:
28
28
  type: string
29
29
  required: false
30
- default: "6-kyu-understand-hamming-distance"
30
+ default: "7-kyu-understand-fizz-buzz"
31
31
  mission-text:
32
32
  type: string
33
33
  required: false
@@ -58,11 +58,11 @@ on:
58
58
  description: "Init mode"
59
59
  type: choice
60
60
  required: false
61
- default: "update"
61
+ default: "purge"
62
62
  options:
63
- - update
64
- - reseed
65
63
  - purge
64
+ - reseed
65
+ - update
66
66
  dry-run:
67
67
  description: "Preview changes without writing files"
68
68
  type: boolean
@@ -72,8 +72,10 @@ on:
72
72
  description: "Mission seed name (purge only)"
73
73
  type: choice
74
74
  required: false
75
- default: "6-kyu-understand-hamming-distance"
75
+ default: "7-kyu-understand-fizz-buzz"
76
76
  options:
77
+ - random
78
+ - generate
77
79
  - 8-kyu-remember-empty
78
80
  - 8-kyu-remember-hello-world
79
81
  - 7-kyu-understand-fizz-buzz
@@ -158,7 +160,7 @@ jobs:
158
160
  with:
159
161
  script: |
160
162
  core.setOutput('dry-run', context.payload.inputs?.['dry-run'] || 'false');
161
- core.setOutput('mission', context.payload.inputs?.['mission-seed'] || '6-kyu-understand-hamming-distance');
163
+ core.setOutput('mission', context.payload.inputs?.['mission-seed'] || '7-kyu-understand-fizz-buzz');
162
164
  core.setOutput('profile', context.payload.inputs?.['profile'] || '');
163
165
  core.setOutput('model', context.payload.inputs?.['model'] || '');
164
166
  core.setOutput('create-seed-issues', context.payload.inputs?.['create-seed-issues'] || 'false');
@@ -171,18 +173,18 @@ jobs:
171
173
  with:
172
174
  ref: ${{ inputs.ref }}
173
175
  dry-run: ${{ inputs.dry-run || 'false' }}
174
- skip-tests: ${{ inputs.mode == 'reseed' || inputs.mode == 'purge' }}
176
+ skip-tests: ${{ inputs.mode != 'update' }}
175
177
  secrets: inherit
176
178
 
177
179
  # Step 2: Reseed/purge and configure (only if mode != update)
178
180
  # Use !cancelled() so purge runs even if update's npm test failed
179
181
  init:
180
182
  needs: [params, update]
181
- if: "!cancelled() && (inputs.mode == 'reseed' || inputs.mode == 'purge')"
183
+ if: "!cancelled() && inputs.mode != 'update'"
182
184
  runs-on: ubuntu-latest
183
185
  env:
184
186
  INIT_MODE: ${{ inputs.mode }}
185
- INIT_MISSION_SEED: ${{ inputs.mission-seed || '6-kyu-understand-hamming-distance' }}
187
+ INIT_MISSION_SEED: ${{ inputs.mission-seed || '7-kyu-understand-fizz-buzz' }}
186
188
  INIT_MISSION_TEXT: ${{ inputs.mission-text }}
187
189
  steps:
188
190
  - uses: actions/checkout@v6
@@ -18,9 +18,10 @@ on:
18
18
  required: false
19
19
  default: ""
20
20
  frequency:
21
- description: "How often the workflow should run"
22
- required: true
21
+ description: "How often the workflow should run (empty = read from agentic-lib.toml)"
22
+ required: false
23
23
  type: string
24
+ default: ""
24
25
  model:
25
26
  description: "Copilot SDK model to use"
26
27
  required: false
@@ -39,16 +40,27 @@ on:
39
40
  workflow_dispatch:
40
41
  inputs:
41
42
  frequency:
42
- description: "How often the workflow should run (maintenance = weekly + remove mission-complete + unlimited budget)"
43
- required: true
43
+ description: "How often the workflow should run (empty = read from agentic-lib.toml, maintenance = weekly + remove mission-complete + unlimited budget)"
44
+ required: false
44
45
  type: choice
46
+ default: ""
45
47
  options:
48
+ - ""
46
49
  - "off"
47
50
  - "maintenance"
48
51
  - "weekly"
49
52
  - "daily"
50
53
  - "hourly"
51
54
  - "continuous"
55
+ focus:
56
+ description: "Focus mode (empty = read from agentic-lib.toml)"
57
+ required: false
58
+ type: choice
59
+ default: ""
60
+ options:
61
+ - ""
62
+ - "mission"
63
+ - "maintenance"
52
64
  model:
53
65
  description: "Copilot SDK model to use (empty = read from agentic-lib.toml)"
54
66
  required: false
@@ -85,16 +97,36 @@ jobs:
85
97
  frequency: ${{ steps.resolve.outputs.frequency }}
86
98
  model: ${{ steps.resolve.outputs.model }}
87
99
  profile: ${{ steps.resolve.outputs.profile }}
100
+ focus: ${{ steps.resolve.outputs.focus }}
88
101
  maintenance: ${{ steps.resolve.outputs.maintenance }}
89
102
  steps:
103
+ - uses: actions/checkout@v6
104
+ with:
105
+ sparse-checkout: agentic-lib.toml
106
+ sparse-checkout-cone-mode: false
90
107
  - id: resolve
91
108
  uses: actions/github-script@v8
92
109
  with:
93
110
  script: |
94
- const frequency = context.payload.inputs?.['frequency'] || 'off';
111
+ const fs = require('fs');
112
+ const tomlPath = 'agentic-lib.toml';
113
+ let tomlContent = '';
114
+ if (fs.existsSync(tomlPath)) tomlContent = fs.readFileSync(tomlPath, 'utf8');
115
+ const readToml = (key) => {
116
+ const m = tomlContent.match(new RegExp(`^\\s*${key}\\s*=\\s*"([^"]*)"`, 'm'));
117
+ return m ? m[1] : '';
118
+ };
119
+ let frequency = context.payload.inputs?.['frequency'] || '';
120
+ if (!frequency) frequency = readToml('supervisor') || 'off';
121
+ const model = context.payload.inputs?.['model'] || '';
122
+ const profile = context.payload.inputs?.['profile'] || '';
123
+ let focus = context.payload.inputs?.['focus'] || '';
124
+ if (!focus) focus = readToml('focus') || 'mission';
125
+ if (frequency === 'maintenance') focus = 'maintenance';
95
126
  core.setOutput('frequency', frequency);
96
- core.setOutput('model', context.payload.inputs?.['model'] || '');
97
- core.setOutput('profile', context.payload.inputs?.['profile'] || '');
127
+ core.setOutput('model', model);
128
+ core.setOutput('profile', profile);
129
+ core.setOutput('focus', focus);
98
130
  core.setOutput('maintenance', frequency === 'maintenance' ? 'true' : 'false');
99
131
 
100
132
  update-schedule:
@@ -116,8 +148,8 @@ jobs:
116
148
  with:
117
149
  script: |
118
150
  const fs = require('fs');
119
- const frequency = '${{ inputs.frequency }}';
120
- const workflowPath = '.github/workflows/agentic-lib-workflow.yml';
151
+ const frequency = '${{ needs.params.outputs.frequency }}';
152
+ const focus = '${{ needs.params.outputs.focus }}';
121
153
  const tomlPath = 'agentic-lib.toml';
122
154
  let model = '${{ inputs.model }}';
123
155
  if (!model && fs.existsSync(tomlPath)) {
@@ -126,75 +158,101 @@ jobs:
126
158
  if (m) model = m[1];
127
159
  }
128
160
  if (!model) model = 'gpt-5-mini';
129
- const profile = '${{ inputs.profile }}';
161
+ let profile = '${{ inputs.profile }}';
162
+ if (!profile && fs.existsSync(tomlPath)) {
163
+ const toml = fs.readFileSync(tomlPath, 'utf8');
164
+ const m = toml.match(/^\s*profile\s*=\s*"([^"]*)"/m);
165
+ if (m) profile = m[1];
166
+ }
130
167
 
131
168
  const isMaintenance = frequency === 'maintenance';
132
169
  const effectiveFrequency = isMaintenance ? 'weekly' : frequency;
133
170
 
134
- // Problem 4 fix: Use a "never fires" cron for off instead of removing the block.
135
- // Keeping the schedule: block permanently avoids GitHub cron de-registration issues.
136
- const SCHEDULE_MAP = {
171
+ // Proportional schedule maps for each workflow
172
+ const WORKFLOW_SCHEDULE_MAP = {
137
173
  off: '0 0 31 2 *',
138
- weekly: '25 6 * * 1',
139
- daily: '25 6 * * *',
140
- hourly: '25 * * * *',
141
- continuous: '5,25,45 * * * *',
174
+ weekly: '25 6 * * 1', // Monday 6:25am
175
+ daily: '25 6 * * *', // Every day 6:25am
176
+ hourly: '25 * * * *', // Every hour at :25
177
+ continuous: '5,25,45 * * * *', // Every 20 min
142
178
  };
179
+ const INIT_SCHEDULE_MAP = {
180
+ off: '0 0 31 2 *',
181
+ weekly: '0 4 1 * *', // 1st of month 4:00am
182
+ daily: '0 4 * * 1', // Monday 4:00am
183
+ hourly: '0 4 * * *', // Every day 4:00am
184
+ continuous: '0 1,5,9,13,17,21 * * *', // Every 4 hours
185
+ };
186
+ const TEST_SCHEDULE_MAP = {
187
+ off: '0 0 31 2 *',
188
+ weekly: '40 6 * * 1', // Monday 6:40am
189
+ daily: '40 6 * * *', // Every day 6:40am
190
+ hourly: '40 0,4,8,12,16,20 * * *', // Every 4 hours at :40
191
+ continuous: '40 * * * *', // Every hour at :40
192
+ };
193
+
194
+ // Helper: update cron in a workflow file
195
+ function updateWorkflowCron(path, cron, label) {
196
+ if (!fs.existsSync(path)) {
197
+ core.info(`${label}: file not found at ${path}, skipping`);
198
+ return;
199
+ }
200
+ let content = fs.readFileSync(path, 'utf8');
201
+ const cronRegex = /- cron: "[^"]*"/;
202
+ if (cronRegex.test(content)) {
203
+ content = content.replace(cronRegex, `- cron: "${cron}"`);
204
+ } else {
205
+ const scheduleBlock = `\n schedule:\n - cron: "${cron}"\n`;
206
+ content = content.replace(/\non:\n/, `\non:${scheduleBlock}`);
207
+ }
208
+ fs.writeFileSync(path, content);
209
+ core.info(`${label}: set cron to "${cron}"`);
210
+ }
211
+
212
+ const workflowPath = '.github/workflows/agentic-lib-workflow.yml';
213
+ const initPath = '.github/workflows/agentic-lib-init.yml';
214
+ const testPath = '.github/workflows/agentic-lib-test.yml';
143
215
 
144
- // Update agentic-lib-workflow.yml schedule
145
- let content = fs.readFileSync(workflowPath, 'utf8');
146
- const cron = SCHEDULE_MAP[effectiveFrequency];
216
+ const workflowCron = WORKFLOW_SCHEDULE_MAP[effectiveFrequency];
217
+ const initCron = INIT_SCHEDULE_MAP[effectiveFrequency];
218
+ const testCron = TEST_SCHEDULE_MAP[effectiveFrequency];
147
219
 
148
220
  // Check if the frequency is already set — skip if no-op (but never skip maintenance)
149
- // Must check BOTH the config file AND the workflow file to avoid desynchronisation
150
221
  const supervisorRegex2 = /^\s*supervisor\s*=\s*"([^"]*)"/m;
151
222
  if (!isMaintenance && fs.existsSync(tomlPath)) {
152
223
  const currentToml = fs.readFileSync(tomlPath, 'utf8');
153
224
  const currentMatch = currentToml.match(supervisorRegex2);
154
225
  const currentFreq = currentMatch ? currentMatch[1] : '';
155
- // Also check the workflow file has the expected cron schedule
226
+ const wfContent = fs.existsSync(workflowPath) ? fs.readFileSync(workflowPath, 'utf8') : '';
156
227
  const cronRegex = /- cron: "([^"]*)"/;
157
- const workflowCronMatch = content.match(cronRegex);
228
+ const workflowCronMatch = wfContent.match(cronRegex);
158
229
  const currentCron = workflowCronMatch ? workflowCronMatch[1] : null;
159
- const expectedCron = cron; // from SCHEDULE_MAP
160
230
  const configMatches = currentFreq === frequency;
161
- const workflowMatches = currentCron === expectedCron;
231
+ const workflowMatches = currentCron === workflowCron;
162
232
  if (configMatches && workflowMatches) {
163
233
  core.info(`Schedule already set to ${frequency} — no change needed`);
164
234
  return;
165
235
  }
166
- if (configMatches && !workflowMatches) {
167
- core.info(`Config says ${frequency} but workflow cron is "${currentCron}" (expected "${expectedCron}") — updating workflow`);
168
- }
169
236
  }
170
237
 
171
- // Replace existing schedule cron or insert a new block
172
- const cronRegexReplace = /- cron: "[^"]*"/;
173
- if (cronRegexReplace.test(content)) {
174
- content = content.replace(cronRegexReplace, `- cron: "${cron}"`);
175
- } else {
176
- // No schedule block exists — insert one after 'on:'
177
- const scheduleBlock = `\n schedule:\n - cron: "${cron}"\n`;
178
- content = content.replace(
179
- /\non:\n/,
180
- `\non:${scheduleBlock}`
181
- );
182
- }
238
+ // Update all three workflow files proportionally
239
+ updateWorkflowCron(workflowPath, workflowCron, 'workflow');
240
+ updateWorkflowCron(initPath, initCron, 'init');
241
+ updateWorkflowCron(testPath, testCron, 'test');
183
242
 
184
- // Stamp the file with current date so the commit is never empty
185
- const dateStamp = `# Schedule updated: ${new Date().toISOString()}`;
186
- const stampRegex = /^# Schedule updated: .*/m;
187
- if (stampRegex.test(content)) {
188
- content = content.replace(stampRegex, dateStamp);
189
- } else {
190
- content = content.replace(
191
- /^(# .*\n)+/m,
192
- (match) => match + dateStamp + '\n'
193
- );
243
+ // Stamp the workflow file with current date
244
+ if (fs.existsSync(workflowPath)) {
245
+ let content = fs.readFileSync(workflowPath, 'utf8');
246
+ const dateStamp = `# Schedule updated: ${new Date().toISOString()}`;
247
+ const stampRegex = /^# Schedule updated: .*/m;
248
+ if (stampRegex.test(content)) {
249
+ content = content.replace(stampRegex, dateStamp);
250
+ } else {
251
+ content = content.replace(/^(# .*\n)+/m, (match) => match + dateStamp + '\n');
252
+ }
253
+ fs.writeFileSync(workflowPath, content);
194
254
  }
195
-
196
- fs.writeFileSync(workflowPath, content);
197
- core.info(`Updated workflow schedule to: ${effectiveFrequency} (cron: ${cron || 'none'})`);
255
+ core.info(`Updated proportional schedules: workflow=${effectiveFrequency}, init=${effectiveFrequency}(proportional), test=${effectiveFrequency}(proportional)`);
198
256
 
199
257
  // Maintenance mode: remove mission-complete/failed signals
200
258
  if (isMaintenance) {
@@ -206,7 +264,7 @@ jobs:
206
264
  }
207
265
  }
208
266
 
209
- // Update agentic-lib.toml with model and supervisor settings
267
+ // Update agentic-lib.toml with model, supervisor, focus, and profile settings
210
268
  if (fs.existsSync(tomlPath)) {
211
269
  let toml = fs.readFileSync(tomlPath, 'utf8');
212
270
 
@@ -227,6 +285,14 @@ jobs:
227
285
  toml = toml.replace(scheduleSupervisorRegex, `$1supervisor = "${frequency}"`);
228
286
  }
229
287
 
288
+ // Update focus
289
+ const focusRegex = /^(\s*focus\s*=\s*)"[^"]*"/m;
290
+ if (focusRegex.test(toml)) {
291
+ toml = toml.replace(focusRegex, `$1"${focus}"`);
292
+ } else if (toml.match(/^\[schedule\]/m)) {
293
+ toml = toml.replace(/^(\s*supervisor\s*=\s*"[^"]*".*$)/m, `$1\nfocus = "${focus}"`);
294
+ }
295
+
230
296
  if (profile) {
231
297
  const profileRegex = /(\[tuning\][^\[]*?)(^\s*profile\s*=\s*"[^"]*")/m;
232
298
  if (profileRegex.test(toml)) {
@@ -244,7 +310,7 @@ jobs:
244
310
  }
245
311
 
246
312
  fs.writeFileSync(tomlPath, toml);
247
- core.info(`Updated agentic-lib.toml: model=${model}, supervisor=${frequency}${profile ? ', profile=' + profile : ''}`);
313
+ core.info(`Updated agentic-lib.toml: model=${model}, supervisor=${frequency}, focus=${focus}${profile ? ', profile=' + profile : ''}`);
248
314
  } else {
249
315
  core.warning('agentic-lib.toml not found — skipping config update');
250
316
  }
@@ -260,7 +326,7 @@ jobs:
260
326
  git config user.email "${TOKEN_ID}+${TOKEN_USER}@users.noreply.github.com"
261
327
  FREQUENCY="${{ inputs.frequency }}"
262
328
  MODEL="${{ inputs.model }}"
263
- git add .github/workflows/agentic-lib-workflow.yml agentic-lib.toml
329
+ git add .github/workflows/agentic-lib-workflow.yml .github/workflows/agentic-lib-init.yml .github/workflows/agentic-lib-test.yml agentic-lib.toml
264
330
  # Stage removed mission files ONLY if maintenance mode deleted them
265
331
  if [ "$FREQUENCY" = "maintenance" ]; then
266
332
  git rm --ignore-unmatch MISSION_COMPLETE.md MISSION_FAILED.md 2>/dev/null || true
@@ -17,7 +17,7 @@ run-name: "agentic-lib-test [${{ github.ref_name }}]"
17
17
 
18
18
  on:
19
19
  #@dist schedule:
20
- #@dist - cron: "40 * * * *"
20
+ #@dist - cron: "0 0 31 2 *"
21
21
  #@dist push:
22
22
  #@dist branches: [main]
23
23
  #@dist paths:
@@ -40,6 +40,10 @@ on:
40
40
  type: string
41
41
  required: false
42
42
  default: "false"
43
+ log-branch:
44
+ type: string
45
+ required: false
46
+ default: "agentic-lib-logs"
43
47
  ref:
44
48
  type: string
45
49
  required: false
@@ -17,7 +17,7 @@ run-name: "agentic-lib-workflow [${{ github.ref_name }}]"
17
17
 
18
18
  on:
19
19
  #@dist schedule:
20
- #@dist - cron: "0 6 * * 1"
20
+ #@dist - cron: "0 0 31 2 *"
21
21
  workflow_call:
22
22
  inputs:
23
23
  ref:
@@ -729,11 +729,30 @@ jobs:
729
729
  echo "- **Features:** ${{ steps.maintain-features.outputs.narrative }}" >> $GITHUB_STEP_SUMMARY
730
730
  echo "- **Library:** ${{ steps.maintain-library.outputs.narrative }}" >> $GITHUB_STEP_SUMMARY
731
731
 
732
+ - name: Check health for commit message
733
+ id: health
734
+ if: github.repository != 'xn-intenton-z2a/agentic-lib' && needs.params.outputs.dry-run != 'true'
735
+ run: |
736
+ if npm ci --ignore-scripts 2>/dev/null; then
737
+ TEST_OUTPUT=$(npm test 2>&1) || true
738
+ PASS_COUNT=$(echo "$TEST_OUTPUT" | grep -oP '\d+ passing' | head -1 || echo "")
739
+ FAIL_COUNT=$(echo "$TEST_OUTPUT" | grep -oP '\d+ failing' | head -1 || echo "")
740
+ if [ -n "$FAIL_COUNT" ]; then
741
+ echo "summary=maintain(features+library): ${PASS_COUNT:-0 passing}, ${FAIL_COUNT} [unstable]" >> $GITHUB_OUTPUT
742
+ elif [ -n "$PASS_COUNT" ]; then
743
+ echo "summary=maintain(features+library): ${PASS_COUNT} [healthy]" >> $GITHUB_OUTPUT
744
+ else
745
+ echo "summary=maintain(features+library): tests completed [healthy]" >> $GITHUB_OUTPUT
746
+ fi
747
+ else
748
+ echo "summary=maintain(features+library): [broken: npm ci failed]" >> $GITHUB_OUTPUT
749
+ fi
750
+
732
751
  - name: Commit and push changes
733
752
  if: github.repository != 'xn-intenton-z2a/agentic-lib' && needs.params.outputs.dry-run != 'true'
734
753
  uses: ./.github/agentic-lib/actions/commit-if-changed
735
754
  with:
736
- commit-message: "agentic-step: maintain features and library"
755
+ commit-message: "${{ steps.health.outputs.summary || 'agentic-step: maintain features and library' }}"
737
756
  push-ref: ${{ github.ref_name }}
738
757
  fail-on-conflict: "false"
739
758
 
@@ -809,6 +828,21 @@ jobs:
809
828
  instructions: ".github/agents/agent-implementation-review.md"
810
829
  model: ${{ needs.params.outputs.model }}
811
830
 
831
+ # Commit MISSION.md checkbox updates (from Fix #6) so downstream jobs see them
832
+ - name: Commit acceptance criteria updates
833
+ if: github.repository != 'xn-intenton-z2a/agentic-lib' && needs.params.outputs.dry-run != 'true'
834
+ run: |
835
+ if git diff --quiet MISSION.md 2>/dev/null; then
836
+ echo "No MISSION.md changes to commit"
837
+ else
838
+ git config user.name "github-actions[bot]"
839
+ git config user.email "github-actions[bot]@users.noreply.github.com"
840
+ git add MISSION.md
841
+ git commit -m "agentic-step: update acceptance criteria checkboxes [skip ci]"
842
+ git pull --rebase origin main 2>/dev/null || true
843
+ git push origin HEAD:main || echo "::warning::Could not push MISSION.md updates"
844
+ fi
845
+
812
846
  - name: Push log to log branch
813
847
  if: github.repository != 'xn-intenton-z2a/agentic-lib' && needs.params.outputs.dry-run != 'true'
814
848
  env:
@@ -1606,6 +1640,15 @@ jobs:
1606
1640
  # echo "tests-passed=true" >> $GITHUB_OUTPUT
1607
1641
  # echo "Behaviour tests passed"
1608
1642
 
1643
+ - name: Sync lockfile if package.json changed
1644
+ if: github.repository != 'xn-intenton-z2a/agentic-lib' && steps.issue.outputs.issue-number != '' && needs.params.outputs.dry-run != 'true'
1645
+ run: |
1646
+ if git diff --name-only | grep -q 'package.json'; then
1647
+ echo "package.json changed — syncing lockfile"
1648
+ npm install --package-lock-only || echo "::warning::Lockfile sync failed"
1649
+ git add package-lock.json 2>/dev/null || true
1650
+ fi
1651
+
1609
1652
  - name: Commit and push
1610
1653
  if: github.repository != 'xn-intenton-z2a/agentic-lib' && steps.issue.outputs.issue-number != '' && needs.params.outputs.dry-run != 'true' && steps.pre-commit-test.outputs.tests-passed == 'true' && steps.pre-commit-behaviour-test.outputs.tests-passed != 'false'
1611
1654
  uses: ./.github/agentic-lib/actions/commit-if-changed
@@ -1741,6 +1784,16 @@ jobs:
1741
1784
  echo "- Website: [${SITE_URL}](${SITE_URL})" >> $GITHUB_STEP_SUMMARY
1742
1785
 
1743
1786
  # W14: Post-merge director check — re-evaluate mission status after dev/PR merges
1787
+ # Pull latest main to include dev merge (checkout was at maintain commit)
1788
+ - name: Pull latest main (include dev merge)
1789
+ if: |
1790
+ needs.params.outputs.mission-complete != 'true' &&
1791
+ needs.params.outputs.dry-run != 'true' &&
1792
+ needs.director.outputs.decision != 'mission-complete' &&
1793
+ needs.director.outputs.decision != 'mission-failed' &&
1794
+ github.repository != 'xn-intenton-z2a/agentic-lib'
1795
+ run: git pull origin main --ff-only 2>/dev/null || true
1796
+
1744
1797
  - name: Fetch log and screenshot from log branch (post-merge director)
1745
1798
  if: |
1746
1799
  needs.params.outputs.mission-complete != 'true' &&
@@ -1831,6 +1884,8 @@ jobs:
1831
1884
  uses: ./.github/workflows/agentic-lib-test.yml
1832
1885
  with:
1833
1886
  ref: ${{ needs.maintain.outputs.commit-sha || github.ref }}
1887
+ push-screenshot: "true"
1888
+ log-branch: ${{ needs.params.outputs.log-branch }}
1834
1889
  secrets: inherit
1835
1890
 
1836
1891
  # ─── Schedule change (if requested) ────────────────────────────────
package/agentic-lib.toml CHANGED
@@ -6,7 +6,8 @@
6
6
  # During init: #@dist transforms restore standard paths for consumer repos.
7
7
 
8
8
  [schedule]
9
- supervisor = "daily" # off | weekly | daily | hourly | continuous
9
+ supervisor = "daily" #@dist "off" # off | weekly | daily | hourly | continuous
10
+ focus = "mission" # mission | maintenance
10
11
 
11
12
  [paths]
12
13
  mission = "test/MISSION.md" #@dist "MISSION.md"
@@ -89,6 +90,11 @@ max-test-output = 4000 # max chars of test output in prompts
89
90
  max-file-listing = 30 # max files in directory listings (0 = unlimited)
90
91
  max-library-index = 2000 # max chars for library index in prompts
91
92
  max-fix-test-output = 8000 # max chars of failed run log in fix-code
93
+ review-issues-cap = 2 # max issues reviewed per batch (conservative for 10 min timeout)
94
+ min-resolved-issues = 1 # mission-complete: minimum closed-as-RESOLVED issues
95
+ min-cumulative-transforms = 1 # mission-complete: minimum transform cycles
96
+ max-source-todos = 2 # mission-complete: max TODO comments in src
97
+ acceptance-criteria-threshold = 30 # mission-complete: % acceptance criteria required
92
98
 
93
99
  [profiles.med]
94
100
  # Balanced — good results, middle ground.
@@ -111,6 +117,11 @@ max-test-output = 10000 # max chars of test output in prompts
111
117
  max-file-listing = 100 # max files in directory listings (0 = unlimited)
112
118
  max-library-index = 5000 # max chars for library index in prompts
113
119
  max-fix-test-output = 15000 # max chars of failed run log in fix-code
120
+ review-issues-cap = 3 # max issues reviewed per batch
121
+ min-resolved-issues = 2 # mission-complete: minimum closed-as-RESOLVED issues
122
+ min-cumulative-transforms = 1 # mission-complete: minimum transform cycles
123
+ max-source-todos = 1 # mission-complete: max TODO comments in src
124
+ acceptance-criteria-threshold = 50 # mission-complete: % acceptance criteria required
114
125
 
115
126
  [profiles.max]
116
127
  # Thorough — maximum context for complex missions.
@@ -133,6 +144,11 @@ max-test-output = 20000 # max chars of test output in prompts
133
144
  max-file-listing = 0 # max files in directory listings (0 = unlimited)
134
145
  max-library-index = 10000 # max chars for library index in prompts
135
146
  max-fix-test-output = 30000 # max chars of failed run log in fix-code
147
+ review-issues-cap = 4 # max issues reviewed per batch (may need step timeout awareness)
148
+ min-resolved-issues = 3 # mission-complete: minimum closed-as-RESOLVED issues
149
+ min-cumulative-transforms = 2 # mission-complete: minimum transform cycles
150
+ max-source-todos = 0 # mission-complete: max TODO comments in src
151
+ acceptance-criteria-threshold = 75 # mission-complete: % acceptance criteria required
136
152
 
137
153
  [goals]
138
154
  # W12/W13: Code coverage thresholds — stated in all code-changing prompts
@@ -144,7 +160,11 @@ min-branch-coverage = 30 # minimum % branch coverage required
144
160
  # All conditions must be met simultaneously.
145
161
  min-resolved-issues = 1 # minimum closed-as-RESOLVED issues since init
146
162
  max-source-todos = 0 # max TODO comments allowed in ./src (0 = none)
147
- # C6: Removed min-dedicated-tests (replaced by cumulative transforms and acceptance criteria)
163
+ acceptance-criteria-threshold = 50 # percentage of acceptance criteria that must be met (0-100)
164
+ min-cumulative-transforms = 1 # minimum transform cycles completed
165
+ require-no-open-issues = true # all issues must be closed
166
+ require-no-open-prs = true # all PRs must be merged/closed
167
+ require-no-critical-gaps = true # no critical implementation gaps
148
168
 
149
169
  [bot]
150
170
  log-prefix = "tmp/agent-log-" #@dist "agent-log-"