@xn-intenton-z2a/agentic-lib 7.4.14 → 7.4.16
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 +42 -7
- package/README.md +23 -12
- package/agentic-lib.toml +2 -2
- package/bin/agentic-lib.js +34 -4
- package/package.json +1 -1
- package/src/actions/agentic-step/index.js +35 -10
- package/src/actions/agentic-step/logging.js +5 -2
- package/src/actions/agentic-step/tasks/direct.js +50 -16
- 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/transform.js +37 -1
- package/src/actions/commit-if-changed/action.yml +2 -1
- package/src/copilot/config.js +2 -2
- package/src/copilot/github-tools.js +8 -2
- package/src/copilot/guards.js +4 -10
- package/src/copilot/state.js +214 -0
- package/src/copilot/telemetry.js +92 -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@v8
|
|
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@v8
|
|
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@v8
|
|
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@v8
|
|
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@v8
|
|
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@v8
|
|
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@v8
|
|
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();
|
|
@@ -590,7 +590,9 @@ jobs:
|
|
|
590
590
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
591
591
|
SCREENSHOT_FILE: ${{ needs.params.outputs.screenshot-file }}
|
|
592
592
|
run: |
|
|
593
|
+
git fetch origin "${LOG_BRANCH}" 2>/dev/null || true
|
|
593
594
|
git show "origin/${LOG_BRANCH}:${SCREENSHOT_FILE}" > "${SCREENSHOT_FILE}" 2>/dev/null || true
|
|
595
|
+
git show "origin/${LOG_BRANCH}:agentic-lib-state.toml" > "agentic-lib-state.toml" 2>/dev/null || true
|
|
594
596
|
|
|
595
597
|
- name: Check mission-complete signal
|
|
596
598
|
id: mission-check
|
|
@@ -700,7 +702,7 @@ jobs:
|
|
|
700
702
|
if: github.repository != 'xn-intenton-z2a/agentic-lib' && needs.params.outputs.dry-run != 'true'
|
|
701
703
|
env:
|
|
702
704
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
703
|
-
run: bash .github/agentic-lib/scripts/push-to-logs.sh agent-log-*.md
|
|
705
|
+
run: bash .github/agentic-lib/scripts/push-to-logs.sh agent-log-*.md agentic-lib-state.toml
|
|
704
706
|
|
|
705
707
|
# ─── Implementation Review: traces mission elements through code/tests/website ──
|
|
706
708
|
implementation-review:
|
|
@@ -724,9 +726,10 @@ jobs:
|
|
|
724
726
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
725
727
|
SCREENSHOT_FILE: ${{ needs.params.outputs.screenshot-file }}
|
|
726
728
|
run: |
|
|
729
|
+
git fetch origin "${LOG_BRANCH}" 2>/dev/null || true
|
|
727
730
|
git show "origin/${LOG_BRANCH}:${SCREENSHOT_FILE}" > "${SCREENSHOT_FILE}" 2>/dev/null || true
|
|
731
|
+
git show "origin/${LOG_BRANCH}:agentic-lib-state.toml" > "agentic-lib-state.toml" 2>/dev/null || true
|
|
728
732
|
mkdir -p .agent-logs
|
|
729
|
-
git fetch origin "${LOG_BRANCH}" 2>/dev/null || true
|
|
730
733
|
for f in $(git ls-tree --name-only "origin/${LOG_BRANCH}" 2>/dev/null | grep '^agent-log-' || true); do
|
|
731
734
|
git show "origin/${LOG_BRANCH}:${f}" > ".agent-logs/${f}" 2>/dev/null || true
|
|
732
735
|
done
|
|
@@ -765,7 +768,7 @@ jobs:
|
|
|
765
768
|
if: github.repository != 'xn-intenton-z2a/agentic-lib' && needs.params.outputs.dry-run != 'true'
|
|
766
769
|
env:
|
|
767
770
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
768
|
-
run: bash .github/agentic-lib/scripts/push-to-logs.sh agent-log-*.md
|
|
771
|
+
run: bash .github/agentic-lib/scripts/push-to-logs.sh agent-log-*.md agentic-lib-state.toml
|
|
769
772
|
|
|
770
773
|
# ─── Director: LLM evaluates mission status (complete/failed/in-progress) ──
|
|
771
774
|
director:
|
|
@@ -789,7 +792,9 @@ jobs:
|
|
|
789
792
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
790
793
|
SCREENSHOT_FILE: ${{ needs.params.outputs.screenshot-file }}
|
|
791
794
|
run: |
|
|
795
|
+
git fetch origin "${LOG_BRANCH}" 2>/dev/null || true
|
|
792
796
|
git show "origin/${LOG_BRANCH}:${SCREENSHOT_FILE}" > "${SCREENSHOT_FILE}" 2>/dev/null || true
|
|
797
|
+
git show "origin/${LOG_BRANCH}:agentic-lib-state.toml" > "agentic-lib-state.toml" 2>/dev/null || true
|
|
793
798
|
|
|
794
799
|
- uses: actions/setup-node@v6
|
|
795
800
|
with:
|
|
@@ -826,7 +831,7 @@ jobs:
|
|
|
826
831
|
if: github.repository != 'xn-intenton-z2a/agentic-lib' && needs.params.outputs.dry-run != 'true'
|
|
827
832
|
env:
|
|
828
833
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
829
|
-
run: bash .github/agentic-lib/scripts/push-to-logs.sh agent-log-*.md
|
|
834
|
+
run: bash .github/agentic-lib/scripts/push-to-logs.sh agent-log-*.md agentic-lib-state.toml
|
|
830
835
|
|
|
831
836
|
# ─── Supervisor: LLM decides what to do (after director evaluates) ──
|
|
832
837
|
supervisor:
|
|
@@ -838,20 +843,48 @@ jobs:
|
|
|
838
843
|
needs.director.outputs.decision != 'mission-complete' &&
|
|
839
844
|
needs.director.outputs.decision != 'mission-failed'
|
|
840
845
|
runs-on: ubuntu-latest
|
|
846
|
+
outputs:
|
|
847
|
+
backoff-skip: ${{ steps.backoff.outputs.skip }}
|
|
841
848
|
steps:
|
|
842
849
|
- uses: actions/checkout@v6
|
|
843
850
|
with:
|
|
844
851
|
fetch-depth: 0
|
|
845
852
|
ref: ${{ needs.maintain.outputs.commit-sha || github.sha }}
|
|
846
853
|
|
|
847
|
-
- name: Fetch log and
|
|
854
|
+
- name: Fetch log, screenshot and state from log branch
|
|
848
855
|
env:
|
|
849
856
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
850
857
|
SCREENSHOT_FILE: ${{ needs.params.outputs.screenshot-file }}
|
|
851
858
|
run: |
|
|
859
|
+
git fetch origin "${LOG_BRANCH}" 2>/dev/null || true
|
|
852
860
|
git show "origin/${LOG_BRANCH}:${SCREENSHOT_FILE}" > "${SCREENSHOT_FILE}" 2>/dev/null || true
|
|
861
|
+
git show "origin/${LOG_BRANCH}:agentic-lib-state.toml" > "agentic-lib-state.toml" 2>/dev/null || true
|
|
862
|
+
|
|
863
|
+
- name: "C15: Check nop backoff"
|
|
864
|
+
id: backoff
|
|
865
|
+
uses: actions/github-script@v8
|
|
866
|
+
with:
|
|
867
|
+
script: |
|
|
868
|
+
const fs = require('fs');
|
|
869
|
+
let nopCount = 0;
|
|
870
|
+
try {
|
|
871
|
+
const content = fs.readFileSync('agentic-lib-state.toml', 'utf8');
|
|
872
|
+
const match = content.match(/cumulative-nop-cycles\s*=\s*(\d+)/);
|
|
873
|
+
if (match) nopCount = parseInt(match[1], 10);
|
|
874
|
+
} catch { /* no state file yet */ }
|
|
875
|
+
core.info(`Consecutive nop cycles: ${nopCount}`);
|
|
876
|
+
let shouldSkip = false;
|
|
877
|
+
if (nopCount > 3) {
|
|
878
|
+
const pow = Math.pow(2, Math.floor(Math.log2(nopCount)));
|
|
879
|
+
if (nopCount !== pow) {
|
|
880
|
+
shouldSkip = true;
|
|
881
|
+
core.info(`Backoff: skipping (nop count ${nopCount}, next run at ${pow * 2})`);
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
core.setOutput('skip', shouldSkip ? 'true' : 'false');
|
|
853
885
|
|
|
854
886
|
- uses: actions/setup-node@v6
|
|
887
|
+
if: steps.backoff.outputs.skip != 'true'
|
|
855
888
|
with:
|
|
856
889
|
node-version: "24"
|
|
857
890
|
|
|
@@ -886,7 +919,7 @@ jobs:
|
|
|
886
919
|
if: github.repository != 'xn-intenton-z2a/agentic-lib' && needs.params.outputs.dry-run != 'true'
|
|
887
920
|
env:
|
|
888
921
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
889
|
-
run: bash .github/agentic-lib/scripts/push-to-logs.sh agent-log-*.md
|
|
922
|
+
run: bash .github/agentic-lib/scripts/push-to-logs.sh agent-log-*.md agentic-lib-state.toml
|
|
890
923
|
|
|
891
924
|
# ─── Fix stuck PRs with failing checks ─────────────────────────────
|
|
892
925
|
fix-stuck:
|
|
@@ -1285,7 +1318,9 @@ jobs:
|
|
|
1285
1318
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
1286
1319
|
SCREENSHOT_FILE: ${{ needs.params.outputs.screenshot-file }}
|
|
1287
1320
|
run: |
|
|
1321
|
+
git fetch origin "${LOG_BRANCH}" 2>/dev/null || true
|
|
1288
1322
|
git show "origin/${LOG_BRANCH}:${SCREENSHOT_FILE}" > "${SCREENSHOT_FILE}" 2>/dev/null || true
|
|
1323
|
+
git show "origin/${LOG_BRANCH}:agentic-lib-state.toml" > "agentic-lib-state.toml" 2>/dev/null || true
|
|
1289
1324
|
|
|
1290
1325
|
- uses: actions/setup-node@v6
|
|
1291
1326
|
with:
|
|
@@ -1455,7 +1490,7 @@ jobs:
|
|
|
1455
1490
|
if: github.repository != 'xn-intenton-z2a/agentic-lib' && needs.params.outputs.dry-run != 'true'
|
|
1456
1491
|
env:
|
|
1457
1492
|
LOG_BRANCH: ${{ needs.params.outputs.log-branch }}
|
|
1458
|
-
run: bash .github/agentic-lib/scripts/push-to-logs.sh agent-log-*.md
|
|
1493
|
+
run: bash .github/agentic-lib/scripts/push-to-logs.sh agent-log-*.md agentic-lib-state.toml
|
|
1459
1494
|
|
|
1460
1495
|
- name: Create PR and attempt merge
|
|
1461
1496
|
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
|
@@ -109,9 +109,9 @@ library-limit = 64 # max library entries in library/ directo
|
|
|
109
109
|
[mission-complete]
|
|
110
110
|
# Thresholds for deterministic mission-complete declaration.
|
|
111
111
|
# All conditions must be met simultaneously.
|
|
112
|
-
min-resolved-issues =
|
|
113
|
-
min-dedicated-tests = 0 # minimum test files that import from src/lib/
|
|
112
|
+
min-resolved-issues = 1 # minimum closed-as-RESOLVED issues since init
|
|
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
117
|
log-prefix = "tmp/agent-log-" #@dist "agent-log-"
|
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)");
|
package/package.json
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
checkInstabilityLabel, countDedicatedTests,
|
|
19
19
|
countOpenIssues, countResolvedIssues, countMdFiles,
|
|
20
20
|
} from "./metrics.js";
|
|
21
|
+
import { readState, writeState, updateStateAfterTask } from "../../copilot/state.js";
|
|
21
22
|
|
|
22
23
|
// Task implementations
|
|
23
24
|
import { resolveIssue } from "./tasks/resolve-issue.js";
|
|
@@ -92,6 +93,9 @@ async function run() {
|
|
|
92
93
|
logFilePath, screenshotFilePath,
|
|
93
94
|
};
|
|
94
95
|
|
|
96
|
+
// C1: Read persistent state from agentic-lib-state.toml
|
|
97
|
+
const state = readState(".");
|
|
98
|
+
|
|
95
99
|
const startTime = Date.now();
|
|
96
100
|
const result = await handler(context);
|
|
97
101
|
const durationMs = Date.now() - startTime;
|
|
@@ -109,14 +113,18 @@ async function run() {
|
|
|
109
113
|
&& await checkInstabilityLabel(context, issueNumber);
|
|
110
114
|
if (isInstability) core.info(`Issue #${issueNumber} has instability label — does not count against budget`);
|
|
111
115
|
const transformationCost = computeTransformationCost(task, result.outcome, isInstability);
|
|
112
|
-
const cumulativeCost = transformationCost;
|
|
113
116
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
117
|
+
// C1/C2: Update persistent state with this task's results
|
|
118
|
+
updateStateAfterTask(state, {
|
|
119
|
+
task,
|
|
120
|
+
outcome: result.outcome || "completed",
|
|
121
|
+
transformationCost,
|
|
122
|
+
tokensUsed: result.tokensUsed || 0,
|
|
123
|
+
durationMs,
|
|
124
|
+
});
|
|
125
|
+
// C2: Use cumulative cost from persistent state (not just this task)
|
|
126
|
+
const cumulativeCost = state.counters["cumulative-transforms"] || 0;
|
|
127
|
+
state.budget["transformation-budget-cap"] = config.transformationBudget || 0;
|
|
120
128
|
|
|
121
129
|
const { featureIssueCount, maintenanceIssueCount } = await countOpenIssues(context);
|
|
122
130
|
if (result.resolvedCount == null) result.resolvedCount = await countResolvedIssues(context);
|
|
@@ -133,22 +141,39 @@ async function run() {
|
|
|
133
141
|
}
|
|
134
142
|
}
|
|
135
143
|
|
|
136
|
-
|
|
144
|
+
// C5: Pass per-task costs for split display
|
|
145
|
+
const taskCosts = {
|
|
146
|
+
transformationCost,
|
|
147
|
+
tokensUsed: result.tokensUsed || 0,
|
|
148
|
+
cumulativeTokens: state.counters["total-tokens"] || 0,
|
|
149
|
+
durationMs,
|
|
150
|
+
cumulativeDurationMs: state.counters["total-duration-ms"] || 0,
|
|
151
|
+
};
|
|
152
|
+
const missionMetrics = buildMissionMetrics(config, result, limitsStatus, cumulativeCost, featureIssueCount, maintenanceIssueCount, taskCosts);
|
|
137
153
|
|
|
138
|
-
// Write standalone agent log file
|
|
154
|
+
// C4: Write standalone agent log file with sequence number
|
|
155
|
+
const seq = state.counters["log-sequence"] || 0;
|
|
139
156
|
try {
|
|
140
157
|
const agentLogFile = writeAgentLog({
|
|
141
158
|
task, outcome: result.outcome || "completed",
|
|
142
159
|
model: result.model || model, durationMs, tokensUsed: result.tokensUsed,
|
|
143
160
|
narrative: result.narrative, contextNotes: result.contextNotes,
|
|
144
161
|
reviewTable: result.reviewTable, completenessAdvice: result.completenessAdvice,
|
|
145
|
-
missionMetrics,
|
|
162
|
+
missionMetrics, sequence: seq,
|
|
146
163
|
});
|
|
147
164
|
core.info(`Agent log written: ${agentLogFile}`);
|
|
148
165
|
} catch (err) {
|
|
149
166
|
core.warning(`Could not write agent log: ${err.message}`);
|
|
150
167
|
}
|
|
151
168
|
|
|
169
|
+
// C1: Write updated state back to agentic-lib-state.toml
|
|
170
|
+
try {
|
|
171
|
+
writeState(".", state);
|
|
172
|
+
core.info(`State written: seq=${seq}, transforms=${cumulativeCost}, nops=${state.counters["cumulative-nop-cycles"]}`);
|
|
173
|
+
} catch (err) {
|
|
174
|
+
core.warning(`Could not write state: ${err.message}`);
|
|
175
|
+
}
|
|
176
|
+
|
|
152
177
|
core.info(`agentic-step completed: outcome=${result.outcome}`);
|
|
153
178
|
} catch (error) {
|
|
154
179
|
core.setFailed(`agentic-step failed: ${error.message}`);
|
|
@@ -182,16 +182,19 @@ export function logActivity({
|
|
|
182
182
|
export function writeAgentLog({
|
|
183
183
|
task, outcome, model, durationMs, narrative,
|
|
184
184
|
reviewTable, completenessAdvice, contextNotes,
|
|
185
|
-
missionMetrics, tokensUsed,
|
|
185
|
+
missionMetrics, tokensUsed, sequence,
|
|
186
186
|
}) {
|
|
187
187
|
const now = new Date();
|
|
188
188
|
const stamp = now.toISOString().replace(/:/g, "-").replace(/\./g, "-");
|
|
189
|
-
|
|
189
|
+
// C4: Include zero-padded sequence number in filename
|
|
190
|
+
const seq = String(sequence || 0).padStart(3, "0");
|
|
191
|
+
const filename = `agent-log-${stamp}-${seq}.md`;
|
|
190
192
|
|
|
191
193
|
const parts = [
|
|
192
194
|
`# Agent Log: ${task} at ${now.toISOString()}`,
|
|
193
195
|
"",
|
|
194
196
|
"## Summary",
|
|
197
|
+
`**Sequence:** ${seq}`,
|
|
195
198
|
`**Task:** ${task}`,
|
|
196
199
|
`**Outcome:** ${outcome}`,
|
|
197
200
|
];
|