@xn-intenton-z2a/agentic-lib 7.4.13 → 7.4.15
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.
- package/.github/agents/agent-apply-fix.md +30 -1
- package/.github/agents/agent-director.md +28 -7
- package/.github/agents/agent-discussion-bot.md +28 -0
- package/.github/agents/agent-implementation-review.md +21 -0
- package/.github/agents/agent-issue-resolution.md +32 -0
- package/.github/agents/agent-iterate.md +33 -0
- package/.github/agents/agent-maintain-features.md +34 -0
- package/.github/agents/agent-maintain-library.md +39 -0
- package/.github/agents/agent-ready-issue.md +21 -0
- package/.github/agents/agent-review-issue.md +16 -0
- package/.github/agents/agent-supervisor.md +60 -0
- package/.github/workflows/agentic-lib-init.yml +76 -11
- package/.github/workflows/agentic-lib-schedule.yml +58 -6
- package/.github/workflows/agentic-lib-test.yml +31 -3
- package/.github/workflows/agentic-lib-update.yml +20 -0
- package/.github/workflows/agentic-lib-workflow.yml +63 -52
- package/README.md +23 -12
- package/agentic-lib.toml +3 -3
- package/bin/agentic-lib.js +34 -4
- package/package.json +1 -1
- package/src/actions/agentic-step/index.js +51 -34
- package/src/actions/agentic-step/logging.js +7 -14
- package/src/actions/agentic-step/tasks/direct.js +52 -11
- package/src/actions/agentic-step/tasks/maintain-features.js +7 -0
- package/src/actions/agentic-step/tasks/maintain-library.js +10 -0
- package/src/actions/agentic-step/tasks/supervise.js +14 -6
- package/src/actions/agentic-step/tasks/transform.js +37 -1
- package/src/actions/commit-if-changed/action.yml +2 -1
- package/src/copilot/config.js +3 -3
- package/src/copilot/guards.js +5 -5
- package/src/copilot/state.js +211 -0
- package/src/copilot/telemetry.js +88 -10
- package/src/seeds/missions/1-dan-create-c64-emulator.md +13 -13
- package/src/seeds/missions/1-dan-create-planning-engine.md +82 -0
- package/src/seeds/missions/1-kyu-create-ray-tracer.md +31 -8
- package/src/seeds/missions/2-dan-create-self-hosted.md +67 -0
- package/src/seeds/missions/2-kyu-create-markdown-compiler.md +48 -0
- package/src/seeds/missions/2-kyu-create-plot-code-lib.md +35 -16
- package/src/seeds/missions/3-kyu-analyze-lunar-lander.md +13 -14
- package/src/seeds/missions/3-kyu-evaluate-time-series-lab.md +22 -28
- package/src/seeds/missions/4-kyu-analyze-json-schema-diff.md +46 -2
- package/src/seeds/missions/4-kyu-apply-cron-engine.md +16 -18
- package/src/seeds/missions/4-kyu-apply-dense-encoding.md +14 -11
- package/src/seeds/missions/4-kyu-apply-owl-ontology.md +47 -0
- package/src/seeds/missions/5-kyu-apply-ascii-face.md +40 -0
- package/src/seeds/missions/5-kyu-apply-string-utils.md +17 -17
- package/src/seeds/missions/6-kyu-understand-hamming-distance.md +12 -12
- package/src/seeds/missions/6-kyu-understand-roman-numerals.md +12 -12
- package/src/seeds/missions/8-kyu-remember-hello-world.md +10 -0
- package/src/seeds/zero-MISSION.md +12 -12
- package/src/seeds/zero-package.json +1 -1
- package/src/seeds/missions/2-dan-create-agi.md +0 -22
- package/src/seeds/missions/2-kyu-evaluate-markdown-compiler.md +0 -33
- package/src/seeds/missions/3-kyu-evaluate-owl-ontology.md +0 -34
- package/src/seeds/missions/5-kyu-create-ascii-face.md +0 -4
|
@@ -79,7 +79,26 @@ permissions:
|
|
|
79
79
|
contents: write
|
|
80
80
|
|
|
81
81
|
jobs:
|
|
82
|
+
params:
|
|
83
|
+
runs-on: ubuntu-latest
|
|
84
|
+
outputs:
|
|
85
|
+
frequency: ${{ steps.resolve.outputs.frequency }}
|
|
86
|
+
model: ${{ steps.resolve.outputs.model }}
|
|
87
|
+
profile: ${{ steps.resolve.outputs.profile }}
|
|
88
|
+
maintenance: ${{ steps.resolve.outputs.maintenance }}
|
|
89
|
+
steps:
|
|
90
|
+
- id: resolve
|
|
91
|
+
uses: actions/github-script@v7
|
|
92
|
+
with:
|
|
93
|
+
script: |
|
|
94
|
+
const frequency = context.payload.inputs?.['frequency'] || 'off';
|
|
95
|
+
core.setOutput('frequency', frequency);
|
|
96
|
+
core.setOutput('model', context.payload.inputs?.['model'] || '');
|
|
97
|
+
core.setOutput('profile', context.payload.inputs?.['profile'] || '');
|
|
98
|
+
core.setOutput('maintenance', frequency === 'maintenance' ? 'true' : 'false');
|
|
99
|
+
|
|
82
100
|
update-schedule:
|
|
101
|
+
needs: [params]
|
|
83
102
|
runs-on: ubuntu-latest
|
|
84
103
|
steps:
|
|
85
104
|
- uses: actions/checkout@v6
|
|
@@ -112,8 +131,10 @@ jobs:
|
|
|
112
131
|
const isMaintenance = frequency === 'maintenance';
|
|
113
132
|
const effectiveFrequency = isMaintenance ? 'weekly' : frequency;
|
|
114
133
|
|
|
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.
|
|
115
136
|
const SCHEDULE_MAP = {
|
|
116
|
-
off:
|
|
137
|
+
off: '0 0 31 2 *',
|
|
117
138
|
weekly: '25 6 * * 1',
|
|
118
139
|
daily: '25 6 * * *',
|
|
119
140
|
hourly: '25 * * * *',
|
|
@@ -147,11 +168,12 @@ jobs:
|
|
|
147
168
|
}
|
|
148
169
|
}
|
|
149
170
|
|
|
150
|
-
//
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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:'
|
|
155
177
|
const scheduleBlock = `\n schedule:\n - cron: "${cron}"\n`;
|
|
156
178
|
content = content.replace(
|
|
157
179
|
/\non:\n/,
|
|
@@ -261,3 +283,33 @@ jobs:
|
|
|
261
283
|
exit 1
|
|
262
284
|
fi
|
|
263
285
|
done
|
|
286
|
+
|
|
287
|
+
- name: "Problem 2 fix: Verify schedule registered with GitHub"
|
|
288
|
+
if: github.repository != 'xn-intenton-z2a/agentic-lib' && inputs.dry-run != 'true' && inputs.dry-run != true
|
|
289
|
+
env:
|
|
290
|
+
GH_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}
|
|
291
|
+
run: |
|
|
292
|
+
echo "Waiting 10s for GitHub to process the push..."
|
|
293
|
+
sleep 10
|
|
294
|
+
WORKFLOW_STATE=$(gh api "repos/${{ github.repository }}/actions/workflows/agentic-lib-workflow.yml" --jq '.state' 2>/dev/null || echo "unknown")
|
|
295
|
+
echo "Workflow state: ${WORKFLOW_STATE}"
|
|
296
|
+
if [ "$WORKFLOW_STATE" != "active" ]; then
|
|
297
|
+
echo "::warning::Workflow state is '${WORKFLOW_STATE}', attempting to enable..."
|
|
298
|
+
gh api "repos/${{ github.repository }}/actions/workflows/agentic-lib-workflow.yml/enable" -X PUT 2>/dev/null || true
|
|
299
|
+
WORKFLOW_STATE=$(gh api "repos/${{ github.repository }}/actions/workflows/agentic-lib-workflow.yml" --jq '.state' 2>/dev/null || echo "unknown")
|
|
300
|
+
echo "Workflow state after enable: ${WORKFLOW_STATE}"
|
|
301
|
+
fi
|
|
302
|
+
# Verify the cron was registered by checking the workflow definition
|
|
303
|
+
FREQUENCY="${{ inputs.frequency }}"
|
|
304
|
+
if [ "$FREQUENCY" != "off" ]; then
|
|
305
|
+
echo "Verifying cron schedule is active..."
|
|
306
|
+
gh api "repos/${{ github.repository }}/actions/workflows" --jq '.workflows[] | select(.name == "agentic-lib-workflow") | "state=\(.state)"' 2>/dev/null || true
|
|
307
|
+
fi
|
|
308
|
+
|
|
309
|
+
- name: Job Summary
|
|
310
|
+
if: always()
|
|
311
|
+
uses: actions/github-script@v7
|
|
312
|
+
with:
|
|
313
|
+
script: |
|
|
314
|
+
const summary = `## Job: update-schedule\n| Key | Value |\n|-----|-------|\n| Status | ${context.job.status || 'completed'} |\n| Frequency | ${{ inputs.frequency }} |\n| Model | ${{ inputs.model || 'default' }} |\n| Profile | ${{ inputs.profile || 'default' }} |`;
|
|
315
|
+
core.summary.addRaw(summary).write();
|
|
@@ -58,7 +58,19 @@ permissions:
|
|
|
58
58
|
issues: write
|
|
59
59
|
|
|
60
60
|
jobs:
|
|
61
|
+
params:
|
|
62
|
+
runs-on: ubuntu-latest
|
|
63
|
+
outputs:
|
|
64
|
+
dry-run: ${{ steps.resolve.outputs.dry-run }}
|
|
65
|
+
steps:
|
|
66
|
+
- id: resolve
|
|
67
|
+
uses: actions/github-script@v7
|
|
68
|
+
with:
|
|
69
|
+
script: |
|
|
70
|
+
core.setOutput('dry-run', context.payload.inputs?.['dry-run'] || 'false');
|
|
71
|
+
|
|
61
72
|
test:
|
|
73
|
+
needs: [params]
|
|
62
74
|
runs-on: ubuntu-latest
|
|
63
75
|
steps:
|
|
64
76
|
- uses: actions/checkout@v6
|
|
@@ -86,6 +98,14 @@ jobs:
|
|
|
86
98
|
- name: Run tests
|
|
87
99
|
run: ${{ steps.config.outputs.test-command }}
|
|
88
100
|
|
|
101
|
+
- name: Job Summary
|
|
102
|
+
if: always()
|
|
103
|
+
uses: actions/github-script@v7
|
|
104
|
+
with:
|
|
105
|
+
script: |
|
|
106
|
+
const summary = `## Job: test\n| Key | Value |\n|-----|-------|\n| Status | ${context.job.status || 'completed'} |`;
|
|
107
|
+
core.summary.addRaw(summary).write();
|
|
108
|
+
|
|
89
109
|
behaviour:
|
|
90
110
|
if: github.repository != 'xn-intenton-z2a/agentic-lib'
|
|
91
111
|
continue-on-error: true
|
|
@@ -139,9 +159,17 @@ jobs:
|
|
|
139
159
|
LOG_BRANCH: ${{ inputs.log-branch || 'agentic-lib-logs' }}
|
|
140
160
|
run: bash .github/agentic-lib/scripts/push-to-logs.sh "${SCREENSHOT_FILE:-SCREENSHOT_INDEX.png}"
|
|
141
161
|
|
|
162
|
+
- name: Job Summary
|
|
163
|
+
if: always()
|
|
164
|
+
uses: actions/github-script@v7
|
|
165
|
+
with:
|
|
166
|
+
script: |
|
|
167
|
+
const summary = `## Job: behaviour\n| Key | Value |\n|-----|-------|\n| Status | ${context.job.status || 'completed'} |\n| Tests Failed | ${{ steps.result.outputs.tests-failed }} |`;
|
|
168
|
+
core.summary.addRaw(summary).write();
|
|
169
|
+
|
|
142
170
|
# ─── Dispatch fix workflow when unit tests fail on main ─────────────
|
|
143
171
|
dispatch-fix:
|
|
144
|
-
needs: [test]
|
|
172
|
+
needs: [params, test]
|
|
145
173
|
if: >-
|
|
146
174
|
!cancelled()
|
|
147
175
|
&& github.ref == 'refs/heads/main'
|
|
@@ -183,7 +211,7 @@ jobs:
|
|
|
183
211
|
|
|
184
212
|
# ─── Report instability: install or unit test failure → automated + instability ──
|
|
185
213
|
report-instability:
|
|
186
|
-
needs: [test]
|
|
214
|
+
needs: [params, test]
|
|
187
215
|
if: >-
|
|
188
216
|
!cancelled()
|
|
189
217
|
&& github.ref == 'refs/heads/main'
|
|
@@ -293,7 +321,7 @@ jobs:
|
|
|
293
321
|
|
|
294
322
|
# ─── Report behaviour failure: behaviour test failure → automated only ──
|
|
295
323
|
report-behaviour:
|
|
296
|
-
needs: [behaviour]
|
|
324
|
+
needs: [params, behaviour]
|
|
297
325
|
if: >-
|
|
298
326
|
!cancelled()
|
|
299
327
|
&& github.ref == 'refs/heads/main'
|
|
@@ -37,7 +37,19 @@ on:
|
|
|
37
37
|
permissions: write-all
|
|
38
38
|
|
|
39
39
|
jobs:
|
|
40
|
+
params:
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
outputs:
|
|
43
|
+
dry-run: ${{ steps.resolve.outputs.dry-run }}
|
|
44
|
+
steps:
|
|
45
|
+
- id: resolve
|
|
46
|
+
uses: actions/github-script@v7
|
|
47
|
+
with:
|
|
48
|
+
script: |
|
|
49
|
+
core.setOutput('dry-run', context.payload.inputs?.['dry-run'] || 'false');
|
|
50
|
+
|
|
40
51
|
update:
|
|
52
|
+
needs: [params]
|
|
41
53
|
runs-on: ubuntu-latest
|
|
42
54
|
steps:
|
|
43
55
|
- uses: actions/checkout@v6
|
|
@@ -109,3 +121,11 @@ jobs:
|
|
|
109
121
|
exit 1
|
|
110
122
|
fi
|
|
111
123
|
done
|
|
124
|
+
|
|
125
|
+
- name: Job Summary
|
|
126
|
+
if: always()
|
|
127
|
+
uses: actions/github-script@v7
|
|
128
|
+
with:
|
|
129
|
+
script: |
|
|
130
|
+
const summary = `## Job: update\n| Key | Value |\n|-----|-------|\n| Status | ${context.job.status || 'completed'} |\n| Dry Run | ${{ inputs.dry-run }} |`;
|
|
131
|
+
core.summary.addRaw(summary).write();
|
|
@@ -178,16 +178,16 @@ jobs:
|
|
|
178
178
|
echo "dry-run=${DRY_RUN}" >> $GITHUB_OUTPUT
|
|
179
179
|
CONFIG='${{ inputs.config-path }}'
|
|
180
180
|
echo "config-path=${CONFIG:-${{ env.configPath }}}" >> $GITHUB_OUTPUT
|
|
181
|
-
# Bot config: log
|
|
182
|
-
|
|
181
|
+
# Bot config: log prefix, log branch, screenshot file
|
|
182
|
+
LOG_PREFIX=""
|
|
183
183
|
LOG_BRANCH=""
|
|
184
184
|
SCREENSHOT=""
|
|
185
185
|
if [ -f "${{ env.configPath }}" ]; then
|
|
186
|
-
|
|
186
|
+
LOG_PREFIX=$(grep '^\s*log-prefix' "${{ env.configPath }}" | head -1 | sed 's/.*= *"\([^"]*\)".*/\1/' || true)
|
|
187
187
|
LOG_BRANCH=$(grep '^\s*log-branch' "${{ env.configPath }}" | head -1 | sed 's/.*= *"\([^"]*\)".*/\1/' || true)
|
|
188
188
|
SCREENSHOT=$(grep '^\s*screenshot-file' "${{ env.configPath }}" | head -1 | sed 's/.*= *"\([^"]*\)".*/\1/' || true)
|
|
189
189
|
fi
|
|
190
|
-
echo "log-
|
|
190
|
+
echo "log-prefix=${LOG_PREFIX:-agent-log-}" >> $GITHUB_OUTPUT
|
|
191
191
|
echo "log-branch=${LOG_BRANCH:-agentic-lib-logs}" >> $GITHUB_OUTPUT
|
|
192
192
|
echo "screenshot-file=${SCREENSHOT:-SCREENSHOT_INDEX.png}" >> $GITHUB_OUTPUT
|
|
193
193
|
outputs:
|
|
@@ -200,7 +200,7 @@ jobs:
|
|
|
200
200
|
pr-number: ${{ steps.normalise.outputs.pr-number }}
|
|
201
201
|
dry-run: ${{ steps.normalise.outputs.dry-run }}
|
|
202
202
|
config-path: ${{ steps.normalise.outputs.config-path }}
|
|
203
|
-
log-
|
|
203
|
+
log-prefix: ${{ steps.normalise.outputs.log-prefix }}
|
|
204
204
|
log-branch: ${{ steps.normalise.outputs.log-branch }}
|
|
205
205
|
screenshot-file: ${{ steps.normalise.outputs.screenshot-file }}
|
|
206
206
|
|
|
@@ -373,7 +373,6 @@ jobs:
|
|
|
373
373
|
id: gather
|
|
374
374
|
uses: actions/github-script@v8
|
|
375
375
|
env:
|
|
376
|
-
LOG_FILE: ${{ needs.params.outputs.log-file }}
|
|
377
376
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
378
377
|
with:
|
|
379
378
|
script: |
|
|
@@ -478,32 +477,28 @@ jobs:
|
|
|
478
477
|
const missionComplete = fs.existsSync('MISSION_COMPLETE.md');
|
|
479
478
|
const missionFailed = fs.existsSync('MISSION_FAILED.md');
|
|
480
479
|
|
|
481
|
-
// Activity log stats (
|
|
482
|
-
const logFile = process.env.LOG_FILE || 'intentïon.md';
|
|
480
|
+
// Activity log stats (from agent-log files on log branch)
|
|
483
481
|
const logBranch = process.env.LOG_BRANCH || 'agentic-lib-logs';
|
|
484
482
|
let activityStats = null;
|
|
485
483
|
try {
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
484
|
+
const { data: tree } = await github.rest.git.getTree({
|
|
485
|
+
owner, repo, tree_sha: logBranch, recursive: false,
|
|
486
|
+
});
|
|
487
|
+
const logFiles = tree.tree
|
|
488
|
+
.filter(f => f.path.startsWith('agent-log-') && f.path.endsWith('.md'))
|
|
489
|
+
.sort((a, b) => a.path.localeCompare(b.path));
|
|
490
|
+
activityStats = { entries: logFiles.length, totalTransformCost: 0 };
|
|
491
|
+
// Sum costs from the most recent 10 log files
|
|
492
|
+
const recent = logFiles.slice(-10);
|
|
493
|
+
for (const lf of recent) {
|
|
489
494
|
try {
|
|
490
495
|
const { data } = await github.rest.repos.getContent({
|
|
491
|
-
owner, repo, path: lf, ref: logBranch,
|
|
496
|
+
owner, repo, path: lf.path, ref: logBranch,
|
|
492
497
|
});
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
// Fall back to local file
|
|
498
|
-
if (!log) {
|
|
499
|
-
const logPath = fs.existsSync(logFile) ? logFile : (fs.existsSync('intention.md') ? 'intention.md' : null);
|
|
500
|
-
if (logPath) log = fs.readFileSync(logPath, 'utf8');
|
|
501
|
-
}
|
|
502
|
-
if (log) {
|
|
503
|
-
const entries = log.split('\n## ').length - 1;
|
|
504
|
-
const costMatches = [...log.matchAll(/\*\*agentic-lib transformation cost:\*\* (\d+)/g)];
|
|
505
|
-
const totalCost = costMatches.reduce((sum, m) => sum + parseInt(m[1], 10), 0);
|
|
506
|
-
activityStats = { entries, totalTransformCost: totalCost };
|
|
498
|
+
const content = Buffer.from(data.content, 'base64').toString('utf8');
|
|
499
|
+
const costMatches = [...content.matchAll(/\*\*agentic-lib transformation cost:\*\* (\d+)/g)];
|
|
500
|
+
activityStats.totalTransformCost += costMatches.reduce((sum, m) => sum + parseInt(m[1], 10), 0);
|
|
501
|
+
} catch { /* skip unreadable files */ }
|
|
507
502
|
}
|
|
508
503
|
} catch (e) {}
|
|
509
504
|
|
|
@@ -592,13 +587,11 @@ jobs:
|
|
|
592
587
|
|
|
593
588
|
- name: Fetch log and screenshot from log branch
|
|
594
589
|
env:
|
|
595
|
-
LOG_FILE: ${{ needs.params.outputs.log-file }}
|
|
596
590
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
597
591
|
SCREENSHOT_FILE: ${{ needs.params.outputs.screenshot-file }}
|
|
598
592
|
run: |
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
done
|
|
593
|
+
git show "origin/${LOG_BRANCH}:${SCREENSHOT_FILE}" > "${SCREENSHOT_FILE}" 2>/dev/null || true
|
|
594
|
+
git show "origin/${LOG_BRANCH}:agentic-lib-state.toml" > "agentic-lib-state.toml" 2>/dev/null || true
|
|
602
595
|
|
|
603
596
|
- name: Check mission-complete signal
|
|
604
597
|
id: mission-check
|
|
@@ -708,7 +701,7 @@ jobs:
|
|
|
708
701
|
if: github.repository != 'xn-intenton-z2a/agentic-lib' && needs.params.outputs.dry-run != 'true'
|
|
709
702
|
env:
|
|
710
703
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
711
|
-
run: bash .github/agentic-lib/scripts/push-to-logs.sh
|
|
704
|
+
run: bash .github/agentic-lib/scripts/push-to-logs.sh agent-log-*.md
|
|
712
705
|
|
|
713
706
|
# ─── Implementation Review: traces mission elements through code/tests/website ──
|
|
714
707
|
implementation-review:
|
|
@@ -729,13 +722,11 @@ jobs:
|
|
|
729
722
|
|
|
730
723
|
- name: Fetch log and agent logs from log branch
|
|
731
724
|
env:
|
|
732
|
-
LOG_FILE: ${{ needs.params.outputs.log-file }}
|
|
733
725
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
734
726
|
SCREENSHOT_FILE: ${{ needs.params.outputs.screenshot-file }}
|
|
735
727
|
run: |
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
done
|
|
728
|
+
git show "origin/${LOG_BRANCH}:${SCREENSHOT_FILE}" > "${SCREENSHOT_FILE}" 2>/dev/null || true
|
|
729
|
+
git show "origin/${LOG_BRANCH}:agentic-lib-state.toml" > "agentic-lib-state.toml" 2>/dev/null || true
|
|
739
730
|
mkdir -p .agent-logs
|
|
740
731
|
git fetch origin "${LOG_BRANCH}" 2>/dev/null || true
|
|
741
732
|
for f in $(git ls-tree --name-only "origin/${LOG_BRANCH}" 2>/dev/null | grep '^agent-log-' || true); do
|
|
@@ -776,7 +767,7 @@ jobs:
|
|
|
776
767
|
if: github.repository != 'xn-intenton-z2a/agentic-lib' && needs.params.outputs.dry-run != 'true'
|
|
777
768
|
env:
|
|
778
769
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
779
|
-
run: bash .github/agentic-lib/scripts/push-to-logs.sh
|
|
770
|
+
run: bash .github/agentic-lib/scripts/push-to-logs.sh agent-log-*.md
|
|
780
771
|
|
|
781
772
|
# ─── Director: LLM evaluates mission status (complete/failed/in-progress) ──
|
|
782
773
|
director:
|
|
@@ -797,13 +788,11 @@ jobs:
|
|
|
797
788
|
|
|
798
789
|
- name: Fetch log and screenshot from log branch
|
|
799
790
|
env:
|
|
800
|
-
LOG_FILE: ${{ needs.params.outputs.log-file }}
|
|
801
791
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
802
792
|
SCREENSHOT_FILE: ${{ needs.params.outputs.screenshot-file }}
|
|
803
793
|
run: |
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
done
|
|
794
|
+
git show "origin/${LOG_BRANCH}:${SCREENSHOT_FILE}" > "${SCREENSHOT_FILE}" 2>/dev/null || true
|
|
795
|
+
git show "origin/${LOG_BRANCH}:agentic-lib-state.toml" > "agentic-lib-state.toml" 2>/dev/null || true
|
|
807
796
|
|
|
808
797
|
- uses: actions/setup-node@v6
|
|
809
798
|
with:
|
|
@@ -840,7 +829,7 @@ jobs:
|
|
|
840
829
|
if: github.repository != 'xn-intenton-z2a/agentic-lib' && needs.params.outputs.dry-run != 'true'
|
|
841
830
|
env:
|
|
842
831
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
843
|
-
run: bash .github/agentic-lib/scripts/push-to-logs.sh
|
|
832
|
+
run: bash .github/agentic-lib/scripts/push-to-logs.sh agent-log-*.md
|
|
844
833
|
|
|
845
834
|
# ─── Supervisor: LLM decides what to do (after director evaluates) ──
|
|
846
835
|
supervisor:
|
|
@@ -852,23 +841,47 @@ jobs:
|
|
|
852
841
|
needs.director.outputs.decision != 'mission-complete' &&
|
|
853
842
|
needs.director.outputs.decision != 'mission-failed'
|
|
854
843
|
runs-on: ubuntu-latest
|
|
844
|
+
outputs:
|
|
845
|
+
backoff-skip: ${{ steps.backoff.outputs.skip }}
|
|
855
846
|
steps:
|
|
856
847
|
- uses: actions/checkout@v6
|
|
857
848
|
with:
|
|
858
849
|
fetch-depth: 0
|
|
859
850
|
ref: ${{ needs.maintain.outputs.commit-sha || github.sha }}
|
|
860
851
|
|
|
861
|
-
- name: Fetch log and
|
|
852
|
+
- name: Fetch log, screenshot and state from log branch
|
|
862
853
|
env:
|
|
863
|
-
LOG_FILE: ${{ needs.params.outputs.log-file }}
|
|
864
854
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
865
855
|
SCREENSHOT_FILE: ${{ needs.params.outputs.screenshot-file }}
|
|
866
856
|
run: |
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
857
|
+
git show "origin/${LOG_BRANCH}:${SCREENSHOT_FILE}" > "${SCREENSHOT_FILE}" 2>/dev/null || true
|
|
858
|
+
git show "origin/${LOG_BRANCH}:agentic-lib-state.toml" > "agentic-lib-state.toml" 2>/dev/null || true
|
|
859
|
+
|
|
860
|
+
- name: "C15: Check nop backoff"
|
|
861
|
+
id: backoff
|
|
862
|
+
uses: actions/github-script@v7
|
|
863
|
+
with:
|
|
864
|
+
script: |
|
|
865
|
+
const fs = require('fs');
|
|
866
|
+
let nopCount = 0;
|
|
867
|
+
try {
|
|
868
|
+
const content = fs.readFileSync('agentic-lib-state.toml', 'utf8');
|
|
869
|
+
const match = content.match(/cumulative-nop-cycles\s*=\s*(\d+)/);
|
|
870
|
+
if (match) nopCount = parseInt(match[1], 10);
|
|
871
|
+
} catch { /* no state file yet */ }
|
|
872
|
+
core.info(`Consecutive nop cycles: ${nopCount}`);
|
|
873
|
+
let shouldSkip = false;
|
|
874
|
+
if (nopCount > 3) {
|
|
875
|
+
const pow = Math.pow(2, Math.floor(Math.log2(nopCount)));
|
|
876
|
+
if (nopCount !== pow) {
|
|
877
|
+
shouldSkip = true;
|
|
878
|
+
core.info(`Backoff: skipping (nop count ${nopCount}, next run at ${pow * 2})`);
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
core.setOutput('skip', shouldSkip ? 'true' : 'false');
|
|
870
882
|
|
|
871
883
|
- uses: actions/setup-node@v6
|
|
884
|
+
if: steps.backoff.outputs.skip != 'true'
|
|
872
885
|
with:
|
|
873
886
|
node-version: "24"
|
|
874
887
|
|
|
@@ -903,7 +916,7 @@ jobs:
|
|
|
903
916
|
if: github.repository != 'xn-intenton-z2a/agentic-lib' && needs.params.outputs.dry-run != 'true'
|
|
904
917
|
env:
|
|
905
918
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
906
|
-
run: bash .github/agentic-lib/scripts/push-to-logs.sh
|
|
919
|
+
run: bash .github/agentic-lib/scripts/push-to-logs.sh agent-log-*.md
|
|
907
920
|
|
|
908
921
|
# ─── Fix stuck PRs with failing checks ─────────────────────────────
|
|
909
922
|
fix-stuck:
|
|
@@ -1299,13 +1312,11 @@ jobs:
|
|
|
1299
1312
|
|
|
1300
1313
|
- name: Fetch log and screenshot from log branch
|
|
1301
1314
|
env:
|
|
1302
|
-
LOG_FILE: ${{ needs.params.outputs.log-file }}
|
|
1303
1315
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
1304
1316
|
SCREENSHOT_FILE: ${{ needs.params.outputs.screenshot-file }}
|
|
1305
1317
|
run: |
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
done
|
|
1318
|
+
git show "origin/${LOG_BRANCH}:${SCREENSHOT_FILE}" > "${SCREENSHOT_FILE}" 2>/dev/null || true
|
|
1319
|
+
git show "origin/${LOG_BRANCH}:agentic-lib-state.toml" > "agentic-lib-state.toml" 2>/dev/null || true
|
|
1309
1320
|
|
|
1310
1321
|
- uses: actions/setup-node@v6
|
|
1311
1322
|
with:
|
|
@@ -1475,7 +1486,7 @@ jobs:
|
|
|
1475
1486
|
if: github.repository != 'xn-intenton-z2a/agentic-lib' && needs.params.outputs.dry-run != 'true'
|
|
1476
1487
|
env:
|
|
1477
1488
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
1478
|
-
run: bash .github/agentic-lib/scripts/push-to-logs.sh
|
|
1489
|
+
run: bash .github/agentic-lib/scripts/push-to-logs.sh agent-log-*.md
|
|
1479
1490
|
|
|
1480
1491
|
- name: Create PR and attempt merge
|
|
1481
1492
|
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'
|
package/README.md
CHANGED
|
@@ -62,13 +62,12 @@ your-repo/
|
|
|
62
62
|
│
|
|
63
63
|
├── .github/
|
|
64
64
|
│ ├── workflows/ # [INIT] 8 workflow files (always overwritten)
|
|
65
|
-
│ │ ├──
|
|
66
|
-
│ │ ├──
|
|
67
|
-
│ │ ├──
|
|
68
|
-
│ │ ├──
|
|
69
|
-
│ │ ├──
|
|
70
|
-
│ │ ├──
|
|
71
|
-
│ │ ├── ci-automerge.yml # CI: auto-merge passing PRs
|
|
65
|
+
│ │ ├── agentic-lib-workflow.yml # Core: supervisor + transform + maintain + review + dev
|
|
66
|
+
│ │ ├── agentic-lib-bot.yml # Bot: respond to GitHub Discussions
|
|
67
|
+
│ │ ├── agentic-lib-test.yml # CI: run unit + behaviour tests, dispatch fixes
|
|
68
|
+
│ │ ├── agentic-lib-init.yml # Infra: init/purge, optional seed issues
|
|
69
|
+
│ │ ├── agentic-lib-update.yml # Infra: update agentic-lib version
|
|
70
|
+
│ │ ├── agentic-lib-schedule.yml # Infra: change supervisor schedule
|
|
72
71
|
│ │ └── test.yml # CI: run tests
|
|
73
72
|
│ │
|
|
74
73
|
│ └── agentic-lib/ # [INIT] Internal infrastructure (always overwritten)
|
|
@@ -187,10 +186,20 @@ profile = "recommended" # min | recommended | max
|
|
|
187
186
|
# model = "gpt-5-mini" # override model per-profile
|
|
188
187
|
# transformation-budget = 8 # max code-changing cycles per run
|
|
189
188
|
|
|
189
|
+
[mission-complete]
|
|
190
|
+
min-resolved-issues = 2 # minimum closed-as-RESOLVED issues since init
|
|
191
|
+
max-source-todos = 0 # max TODO comments allowed in ./src (0 = none)
|
|
192
|
+
|
|
190
193
|
[bot]
|
|
191
|
-
log-
|
|
194
|
+
log-prefix = "agent-log-"
|
|
195
|
+
log-branch = "agentic-lib-logs"
|
|
196
|
+
screenshot-file = "SCREENSHOT_INDEX.png"
|
|
192
197
|
```
|
|
193
198
|
|
|
199
|
+
### Persistent State
|
|
200
|
+
|
|
201
|
+
The system maintains `agentic-lib-state.toml` on the `agentic-lib-logs` branch to track counters, budget, and status across workflow runs. This file is automatically created on `init --purge` and updated after each `agentic-step` invocation. It tracks cumulative transforms, token usage, consecutive nop cycles (for backoff), and mission status.
|
|
202
|
+
|
|
194
203
|
### Tuning Profiles
|
|
195
204
|
|
|
196
205
|
The `profile` setting controls all tuning defaults. Three profiles are built in:
|
|
@@ -219,6 +228,7 @@ The core of the system is a single GitHub Action that handles all autonomous tas
|
|
|
219
228
|
| `enhance-issue` | Add detail and acceptance criteria to issues |
|
|
220
229
|
| `review-issue` | Review and close resolved issues |
|
|
221
230
|
| `discussions` | Respond to GitHub Discussions |
|
|
231
|
+
| `implementation-review` | Review implementation completeness against mission |
|
|
222
232
|
|
|
223
233
|
Each task calls the GitHub Copilot SDK with context assembled from your repository (mission, code, tests, features) and writes changes back to the working tree. The supervisor can dispatch any of the other tasks via workflow dispatch.
|
|
224
234
|
|
|
@@ -321,19 +331,20 @@ The session uses SDK hooks for observability (tool call tracking, error recovery
|
|
|
321
331
|
| `7-kyu-understand-fizz-buzz` | 7 kyu | Understand | Classic FizzBuzz |
|
|
322
332
|
| `6-kyu-understand-hamming-distance` | 6 kyu | Understand | Hamming distance (strings + bits) |
|
|
323
333
|
| `6-kyu-understand-roman-numerals` | 6 kyu | Understand | Roman numeral conversion |
|
|
324
|
-
| `5-kyu-
|
|
334
|
+
| `5-kyu-apply-ascii-face` | 5 kyu | Apply | ASCII face art |
|
|
325
335
|
| `5-kyu-apply-string-utils` | 5 kyu | Apply | 10 string utility functions |
|
|
326
336
|
| `4-kyu-apply-cron-engine` | 4 kyu | Apply | Cron expression parser |
|
|
327
337
|
| `4-kyu-apply-dense-encoding` | 4 kyu | Apply | Dense binary encoding |
|
|
328
338
|
| `4-kyu-analyze-json-schema-diff` | 4 kyu | Analyze | JSON Schema diff |
|
|
339
|
+
| `4-kyu-apply-owl-ontology` | 4 kyu | Apply | OWL ontology processor |
|
|
329
340
|
| `3-kyu-analyze-lunar-lander` | 3 kyu | Analyze | Lunar lander simulation |
|
|
330
341
|
| `3-kyu-evaluate-time-series-lab` | 3 kyu | Evaluate | Time series analysis |
|
|
331
|
-
| `
|
|
332
|
-
| `2-kyu-evaluate-markdown-compiler` | 2 kyu | Evaluate | Markdown compiler |
|
|
342
|
+
| `2-kyu-create-markdown-compiler` | 2 kyu | Create | Markdown compiler |
|
|
333
343
|
| `2-kyu-create-plot-code-lib` | 2 kyu | Create | Code visualization library |
|
|
334
344
|
| `1-kyu-create-ray-tracer` | 1 kyu | Create | Ray tracer |
|
|
335
345
|
| `1-dan-create-c64-emulator` | 1 dan | Create | C64 emulator |
|
|
336
|
-
| `
|
|
346
|
+
| `1-dan-create-planning-engine` | 1 dan | Create | Planning engine with POP and belief revision |
|
|
347
|
+
| `2-dan-create-self-hosted` | 2 dan | Create | Self-hosting bootstrap tests |
|
|
337
348
|
|
|
338
349
|
### Running Local Benchmarks
|
|
339
350
|
|
package/agentic-lib.toml
CHANGED
|
@@ -110,10 +110,10 @@ library-limit = 64 # max library entries in library/ directo
|
|
|
110
110
|
# Thresholds for deterministic mission-complete declaration.
|
|
111
111
|
# All conditions must be met simultaneously.
|
|
112
112
|
min-resolved-issues = 2 # minimum closed-as-RESOLVED issues since init
|
|
113
|
-
min-dedicated-tests = 0 # minimum test files that import from src/lib/
|
|
114
113
|
max-source-todos = 0 # max TODO comments allowed in ./src (0 = none)
|
|
114
|
+
# C6: Removed min-dedicated-tests (replaced by cumulative transforms and acceptance criteria)
|
|
115
115
|
|
|
116
116
|
[bot]
|
|
117
|
-
log-
|
|
118
|
-
log-branch = "agentic-lib-logs"
|
|
117
|
+
log-prefix = "tmp/agent-log-" #@dist "agent-log-"
|
|
118
|
+
log-branch = "main" #@dist "agentic-lib-logs"
|
|
119
119
|
screenshot-file = "SCREENSHOT_INDEX.png"
|
package/bin/agentic-lib.js
CHANGED
|
@@ -1186,14 +1186,44 @@ function initPurgeGitHub() {
|
|
|
1186
1186
|
ghExec(`gh api repos/${repoSlug}/git/refs/heads/agentic-lib-logs -X DELETE`);
|
|
1187
1187
|
console.log(" DELETE: existing agentic-lib-logs branch");
|
|
1188
1188
|
} catch { /* branch may not exist */ }
|
|
1189
|
-
// Create orphan agentic-lib-logs branch with
|
|
1190
|
-
//
|
|
1191
|
-
const
|
|
1189
|
+
// Create orphan agentic-lib-logs branch with initial state file
|
|
1190
|
+
// C1: Include agentic-lib-state.toml with default state
|
|
1191
|
+
const stateContent = [
|
|
1192
|
+
"# agentic-lib-state.toml — Persistent state across workflow runs",
|
|
1193
|
+
"# Written to the agentic-lib-logs branch by each agentic-step invocation",
|
|
1194
|
+
"",
|
|
1195
|
+
"[counters]",
|
|
1196
|
+
"log-sequence = 0",
|
|
1197
|
+
"cumulative-transforms = 0",
|
|
1198
|
+
"cumulative-maintain-features = 0",
|
|
1199
|
+
"cumulative-maintain-library = 0",
|
|
1200
|
+
"cumulative-nop-cycles = 0",
|
|
1201
|
+
"total-tokens = 0",
|
|
1202
|
+
"",
|
|
1203
|
+
"[budget]",
|
|
1204
|
+
"transformation-budget-used = 0",
|
|
1205
|
+
"transformation-budget-cap = 0",
|
|
1206
|
+
"",
|
|
1207
|
+
"[status]",
|
|
1208
|
+
'mission-complete = false',
|
|
1209
|
+
'mission-failed = false',
|
|
1210
|
+
'mission-failed-reason = ""',
|
|
1211
|
+
'last-transform-at = ""',
|
|
1212
|
+
'last-non-nop-at = ""',
|
|
1213
|
+
"",
|
|
1214
|
+
"[schedule]",
|
|
1215
|
+
'current = ""',
|
|
1216
|
+
"auto-disabled = false",
|
|
1217
|
+
'auto-disabled-reason = ""',
|
|
1218
|
+
"",
|
|
1219
|
+
].join("\n");
|
|
1220
|
+
const stateBlob = JSON.parse(ghExec(`gh api repos/${repoSlug}/git/blobs -X POST -f "content=${stateContent.replace(/"/g, '\\"')}" -f "encoding=utf-8"`));
|
|
1221
|
+
const emptyTree = JSON.parse(ghExec(`gh api repos/${repoSlug}/git/trees -X POST -f "tree[0][path]=.gitkeep" -f "tree[0][mode]=100644" -f "tree[0][type]=blob" -f "tree[0][content]=" -f "tree[1][path]=agentic-lib-state.toml" -f "tree[1][mode]=100644" -f "tree[1][type]=blob" -f "tree[1][sha]=${stateBlob.sha}"`));
|
|
1192
1222
|
const commitData = JSON.parse(ghExec(
|
|
1193
1223
|
`gh api repos/${repoSlug}/git/commits -X POST -f "message=init agentic-lib-logs branch" -f "tree=${emptyTree.sha}"`,
|
|
1194
1224
|
));
|
|
1195
1225
|
ghExec(`gh api repos/${repoSlug}/git/refs -X POST -f "ref=refs/heads/agentic-lib-logs" -f "sha=${commitData.sha}"`);
|
|
1196
|
-
console.log(" CREATE: agentic-lib-logs orphan branch");
|
|
1226
|
+
console.log(" CREATE: agentic-lib-logs orphan branch (with agentic-lib-state.toml)");
|
|
1197
1227
|
initChanges++;
|
|
1198
1228
|
} else {
|
|
1199
1229
|
console.log(" CREATE: agentic-lib-logs orphan branch (dry run)");
|