crewly 1.20.419 → 1.20.421
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/config/skills/agent/core/project-tickets/SKILL.md +21 -0
- package/config/skills/agent/core/project-tickets/execute.sh +15 -5
- package/config/skills/agent/core/record-learning/SKILL.md +12 -1
- package/config/skills/agent/core/record-learning/execute.sh +24 -2
- package/config/skills/team-leader/decide-correction/SKILL.md +65 -0
- package/config/skills/team-leader/decide-correction/execute.sh +63 -0
- package/config/skills/team-leader/handle-failure/SKILL.md +2 -0
- package/config/skills/team-leader/handle-failure/execute.sh +18 -0
- package/dist/backend/backend/src/constants.d.ts +35 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +36 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/memory/memory.controller.d.ts +42 -2
- package/dist/backend/backend/src/controllers/memory/memory.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/memory/memory.controller.js +111 -4
- package/dist/backend/backend/src/controllers/memory/memory.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/memory/memory.routes.d.ts +3 -0
- package/dist/backend/backend/src/controllers/memory/memory.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/memory/memory.routes.js +7 -1
- package/dist/backend/backend/src/controllers/memory/memory.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.d.ts +8 -0
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.js +28 -0
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.routes.d.ts +1 -0
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.routes.js +4 -1
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.routes.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +25 -0
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/services/memory/correction-ladder.service.d.ts +225 -0
- package/dist/backend/backend/src/services/memory/correction-ladder.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/memory/correction-ladder.service.js +335 -0
- package/dist/backend/backend/src/services/memory/correction-ladder.service.js.map +1 -0
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-retro.d.ts +99 -1
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-retro.d.ts.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-retro.js +188 -16
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot-retro.js.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.d.ts +53 -4
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.js +226 -27
- package/dist/backend/backend/src/services/project-tickets/ticket-autopilot.service.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +35 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +36 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/package.json +1 -1
|
@@ -295,6 +295,27 @@ become backlog tickets on the Crewly project, deduplicated and at most 3 a
|
|
|
295
295
|
day, and the owner approves them with one card. Never file harness gaps as
|
|
296
296
|
tickets yourself.
|
|
297
297
|
|
|
298
|
+
### Weekly cross-team retro (orchestrator)
|
|
299
|
+
|
|
300
|
+
Once a week (Monday 09:00, or the first tick after) the orchestrator gets one
|
|
301
|
+
`autopilot_retro` WorkItem titled `Weekly autopilot retro: <week>` when at
|
|
302
|
+
least one lead filed a daily retro that ISO week. The brief lists every
|
|
303
|
+
project's week numbers, its daily retro pages and the harness gaps filed. Read
|
|
304
|
+
the pages, name what repeated across teams and what only Crewly can fix, then
|
|
305
|
+
file it:
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
bash execute.sh retro --week 2026-W44 \
|
|
309
|
+
--summary "Three teams stalled on owner copy approvals; CE and Flopost both lost a day to a stopped member shown as busy." \
|
|
310
|
+
--problem "harness_gap|Triage brief shows stopped members as busy|Seen in CE 10-27 and Flopost 10-29 retros" \
|
|
311
|
+
--problem "owner_dependency|Copy approvals waited >3h in 4 of 7 days"
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Same problem classes and limits as the daily retro. Crewly writes the page to
|
|
315
|
+
the global wiki (`llm-curated/autopilot-retros/weekly/<week>.md`) and files the
|
|
316
|
+
harness gaps on the Crewly project with one owner card. Only the owner or the
|
|
317
|
+
orchestrator may file it.
|
|
318
|
+
|
|
298
319
|
### What to look for
|
|
299
320
|
|
|
300
321
|
Read yesterday's run with `trace-read` first; each problem names the stage
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
# bash execute.sh stats --project P [--days 14] [--label feed] (owner / orc / lead)
|
|
32
32
|
# bash execute.sh runs --project P [--days 7] [--label feed] (owner / orc / lead)
|
|
33
33
|
# bash execute.sh retro --project P --day YYYY-MM-DD --summary "…" [--problem "class|title|detail|evidence" …]
|
|
34
|
+
# bash execute.sh retro --week YYYY-Www --summary "…" [--problem … …] (orchestrator: weekly cross-team retro)
|
|
34
35
|
# bash execute.sh self-review --project P --gap "…" [--moved "…"] --next-bet "…"
|
|
35
36
|
# bash execute.sh '{"action":"create","project":"P","title":"…"}'
|
|
36
37
|
#
|
|
@@ -100,6 +101,8 @@ Usage:
|
|
|
100
101
|
Team lead: file the daily autopilot retro.
|
|
101
102
|
class = agent_judgment | missing_skill |
|
|
102
103
|
harness_gap | owner_dependency
|
|
104
|
+
bash execute.sh retro --week YYYY-Www --summary "…" [--problem … …]
|
|
105
|
+
Orchestrator: file the weekly cross-team retro.
|
|
103
106
|
bash execute.sh self-review --project P --gap "…" [--moved "…"] --next-bet "…"
|
|
104
107
|
Team lead: file the autopilot self-review (gap to
|
|
105
108
|
the target, what moved it, the next bet)
|
|
@@ -114,7 +117,7 @@ STATUS=""; SOURCE=""; REQUEST_ID=""; NOTE=""; OWNER_REVIEW=""; ASSIGNEE=""; STAR
|
|
|
114
117
|
ACCEPTANCE_JSON="null"
|
|
115
118
|
HAS_DESCRIPTION=0
|
|
116
119
|
QUESTION=""; CLEAR=""; OPTIONS_JSON="[]"; DEFAULT_OPT=""; DEADLINE=""; SENSITIVE=""; AP_ENABLED=""; AP_DRIVER=""; AP_BUDGET=""; AP_MAX=""
|
|
117
|
-
AP_RETRO=""; AP_REPLANS=""; AP_REPLAN_TTL=""; DAYS=""; LABEL=""; DAY=""; SUMMARY=""; PROBLEMS_JSON="[]"
|
|
120
|
+
AP_RETRO=""; AP_REPLANS=""; AP_REPLAN_TTL=""; DAYS=""; LABEL=""; DAY=""; WEEK=""; SUMMARY=""; PROBLEMS_JSON="[]"
|
|
118
121
|
DEFER_UNTIL=""; AP_SKIP=""; HOLD=""; HAS_HOLD=0
|
|
119
122
|
METRIC=""; AP_SPEED=""; GAP=""; MOVED=""; NEXT_BET=""
|
|
120
123
|
|
|
@@ -211,6 +214,7 @@ while [[ $# -gt 0 ]]; do
|
|
|
211
214
|
--days) [ $# -ge 2 ] || error_exit "--days requires a value"; DAYS="$2"; shift 2 ;;
|
|
212
215
|
--label) [ $# -ge 2 ] || error_exit "--label requires a value"; LABEL="$2"; shift 2 ;;
|
|
213
216
|
--day) [ $# -ge 2 ] || error_exit "--day requires a value"; DAY="$2"; shift 2 ;;
|
|
217
|
+
--week) [ $# -ge 2 ] || error_exit "--week requires YYYY-Www"; WEEK="$2"; shift 2 ;;
|
|
214
218
|
--summary) [ $# -ge 2 ] || error_exit "--summary requires a value"; SUMMARY="$2"; shift 2 ;;
|
|
215
219
|
--problem) [ $# -ge 2 ] || error_exit "--problem requires \"class|title|detail|evidence\""
|
|
216
220
|
PROBLEMS_JSON=$(jq -c --arg p "$2" '. + [($p | split("|")) as $f | {class: ($f[0] // "" | gsub("^\\s+|\\s+$"; "")), title: ($f[1] // "")} + (if ($f[2] // "") != "" then {detail: $f[2]} else {} end) + (if ($f[3:] | join("|")) != "" then {evidence: ($f[3:] | join("|"))} else {} end)]' <<<"$PROBLEMS_JSON"); shift 2 ;;
|
|
@@ -369,11 +373,17 @@ case "$ACTION" in
|
|
|
369
373
|
fi
|
|
370
374
|
;;
|
|
371
375
|
retro)
|
|
372
|
-
require_param "project" "$PROJECT"
|
|
373
|
-
require_param "day (--day YYYY-MM-DD)" "$DAY"
|
|
374
376
|
require_param "summary (--summary)" "$SUMMARY"
|
|
375
|
-
|
|
376
|
-
|
|
377
|
+
if [ -n "$WEEK" ]; then
|
|
378
|
+
# Weekly cross-team retro (owner / orchestrator): no project, the week is the scope.
|
|
379
|
+
BODY=$(jq -n --arg w "$WEEK" --arg s "$SUMMARY" --argjson p "$PROBLEMS_JSON" '{week: $w, summary: $s, problems: $p}')
|
|
380
|
+
api_call POST "/project-ticket-autopilot/weekly-retro" "$BODY" | jq '{success, retro: .data, error}'
|
|
381
|
+
else
|
|
382
|
+
require_param "project" "$PROJECT"
|
|
383
|
+
require_param "day (--day YYYY-MM-DD)" "$DAY"
|
|
384
|
+
BODY=$(jq -n --arg d "$DAY" --arg s "$SUMMARY" --argjson p "$PROBLEMS_JSON" '{day: $d, summary: $s, problems: $p}')
|
|
385
|
+
api_call POST "/project-ticket-autopilot/$(enc "$PROJECT")/retro" "$BODY" | jq '{success, retro: .data, error}'
|
|
386
|
+
fi
|
|
377
387
|
;;
|
|
378
388
|
self-review)
|
|
379
389
|
require_param "project" "$PROJECT"
|
|
@@ -49,6 +49,14 @@ Record a learning or insight gained during task execution. These learnings are s
|
|
|
49
49
|
| `--project` / `-p` | `projectPath` | Yes | Absolute path to the project |
|
|
50
50
|
| `--learning` / `-l` | `learning` | Yes | The learning or insight (or pipe via stdin) |
|
|
51
51
|
| `--learning-file` | — | No | Read learning from a file path |
|
|
52
|
+
| `--class` | `correctionClass` | No | Correction class slug (e.g. `git-add-all`) when this learning records a **correction** — see below |
|
|
53
|
+
| `--task` | `relatedTask` | No | Ticket / WorkItem the learning came from |
|
|
54
|
+
|
|
55
|
+
## Corrections: give them a class
|
|
56
|
+
|
|
57
|
+
When the learning is a correction — someone told you (or you found out) that a way of working was wrong — add `--class <slug>`: a short, stable name for the *kind* of mistake, not this instance of it (`git-add-all`, `skip-tests-before-pr`, `owner-thread-status-lines`). Reuse the same slug every time the same kind comes back; check with `GET /api/memory/corrections?projectPath=…` if unsure.
|
|
58
|
+
|
|
59
|
+
Why: prose is read every turn and still lets the same mistake back in. The second time a class is recorded in a project, the team lead gets one WorkItem asking whether it can be made impossible (structural change), caught before merge (lint/test/CI), caught when it happens (hook), or must stay prose — and records the choice. Without a class, a correction is just another line in memory.
|
|
52
60
|
|
|
53
61
|
---
|
|
54
62
|
|
|
@@ -90,6 +98,9 @@ echo "Don't use git add -A — it catches .env files" | bash execute.sh --agent
|
|
|
90
98
|
|
|
91
99
|
# Learning from file
|
|
92
100
|
bash execute.sh --agent dev-1 --role developer --project /projects/app --learning-file /tmp/insight.txt
|
|
101
|
+
|
|
102
|
+
# A correction, classed so a repeat reaches the team lead
|
|
103
|
+
bash execute.sh --agent dev-1 --role developer --project /projects/app --class git-add-all --task CREW-42 --learning "[[git]] Never git add -A in this repo: it stages .env. Caught in CREW-42 review."
|
|
93
104
|
```
|
|
94
105
|
|
|
95
106
|
## Examples — Legacy JSON (backward compatible)
|
|
@@ -100,4 +111,4 @@ bash execute.sh '{"agentId":"dev-1","agentRole":"developer","projectPath":"/proj
|
|
|
100
111
|
|
|
101
112
|
## Output
|
|
102
113
|
|
|
103
|
-
JSON confirmation that the learning was recorded.
|
|
114
|
+
JSON confirmation that the learning was recorded. With `--class`, also `correction: { class, count, raised }` — `raised: true` means this occurrence sent the team lead the ladder WorkItem.
|
|
@@ -22,6 +22,8 @@ AGENT_ID=""
|
|
|
22
22
|
AGENT_ROLE=""
|
|
23
23
|
PROJECT_PATH=""
|
|
24
24
|
LEARNING=""
|
|
25
|
+
CORRECTION_CLASS=""
|
|
26
|
+
RELATED_TASK=""
|
|
25
27
|
STRICT=0
|
|
26
28
|
SKIP_PREFLIGHT=0
|
|
27
29
|
|
|
@@ -53,6 +55,14 @@ while [[ $# -gt 0 ]]; do
|
|
|
53
55
|
LEARNING="$(cat "$2")"
|
|
54
56
|
shift 2
|
|
55
57
|
;;
|
|
58
|
+
--class)
|
|
59
|
+
CORRECTION_CLASS="$2"
|
|
60
|
+
shift 2
|
|
61
|
+
;;
|
|
62
|
+
--task)
|
|
63
|
+
RELATED_TASK="$2"
|
|
64
|
+
shift 2
|
|
65
|
+
;;
|
|
56
66
|
--strict)
|
|
57
67
|
STRICT=1
|
|
58
68
|
shift
|
|
@@ -67,7 +77,12 @@ while [[ $# -gt 0 ]]; do
|
|
|
67
77
|
;;
|
|
68
78
|
--help|-h)
|
|
69
79
|
cat <<'EOF'
|
|
70
|
-
Usage: execute.sh --agent <id> --role <role> --project <path> --learning '<text>' [--strict] [--no-preflight]
|
|
80
|
+
Usage: execute.sh --agent <id> --role <role> --project <path> --learning '<text>' [--class <slug>] [--task <id>] [--strict] [--no-preflight]
|
|
81
|
+
|
|
82
|
+
--class <slug> This learning is a correction of kind <slug> (e.g. git-add-all).
|
|
83
|
+
The second time a class is recorded, the team lead gets a
|
|
84
|
+
WorkItem asking for a check in code instead of more prose (#810).
|
|
85
|
+
--task <id> Ticket / WorkItem the learning came from.
|
|
71
86
|
|
|
72
87
|
Karpathy-lite preflight rules (see SKILL.md):
|
|
73
88
|
1. [[Entity]] opener (HARD)
|
|
@@ -113,6 +128,8 @@ if [ -n "$INPUT_JSON" ]; then
|
|
|
113
128
|
[ -z "$AGENT_ROLE" ] && AGENT_ROLE=$(printf '%s' "$INPUT" | jq -r '.agentRole // empty')
|
|
114
129
|
[ -z "$PROJECT_PATH" ] && PROJECT_PATH=$(printf '%s' "$INPUT" | jq -r '.projectPath // empty')
|
|
115
130
|
[ -z "$LEARNING" ] && LEARNING=$(printf '%s' "$INPUT" | jq -r '.learning // empty')
|
|
131
|
+
[ -z "$CORRECTION_CLASS" ] && CORRECTION_CLASS=$(printf '%s' "$INPUT" | jq -r '.correctionClass // empty')
|
|
132
|
+
[ -z "$RELATED_TASK" ] && RELATED_TASK=$(printf '%s' "$INPUT" | jq -r '.relatedTask // empty')
|
|
116
133
|
if [ "$STRICT" -eq 0 ]; then
|
|
117
134
|
JSON_STRICT=$(printf '%s' "$INPUT" | jq -r '.strict // empty')
|
|
118
135
|
[ "$JSON_STRICT" = "true" ] && STRICT=1
|
|
@@ -176,12 +193,17 @@ export _LRN_ROLE="$AGENT_ROLE"
|
|
|
176
193
|
export _LRN_PROJECT="$PROJECT_PATH"
|
|
177
194
|
export _LRN_CONTENT="$LEARNING"
|
|
178
195
|
export _LRN_STRICT="$STRICT"
|
|
196
|
+
export _LRN_CLASS="$CORRECTION_CLASS"
|
|
197
|
+
export _LRN_TASK="$RELATED_TASK"
|
|
179
198
|
|
|
180
199
|
if [ "$STRICT" -eq 1 ]; then
|
|
181
200
|
BODY=$(jq -n '{agentId: env._LRN_AGENT, agentRole: env._LRN_ROLE, projectPath: env._LRN_PROJECT, learning: env._LRN_CONTENT, strict: true}')
|
|
182
201
|
else
|
|
183
202
|
BODY=$(jq -n '{agentId: env._LRN_AGENT, agentRole: env._LRN_ROLE, projectPath: env._LRN_PROJECT, learning: env._LRN_CONTENT}')
|
|
184
203
|
fi
|
|
185
|
-
|
|
204
|
+
# Optional fields: a correction class (ladder, #810) and the task it came from.
|
|
205
|
+
[ -n "$CORRECTION_CLASS" ] && BODY=$(printf '%s' "$BODY" | jq '. + {correctionClass: env._LRN_CLASS}')
|
|
206
|
+
[ -n "$RELATED_TASK" ] && BODY=$(printf '%s' "$BODY" | jq '. + {relatedTask: env._LRN_TASK}')
|
|
207
|
+
unset _LRN_AGENT _LRN_ROLE _LRN_PROJECT _LRN_CONTENT _LRN_STRICT _LRN_CLASS _LRN_TASK
|
|
186
208
|
|
|
187
209
|
api_call POST "/memory/record-learning" "$BODY"
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Decide Correction
|
|
3
|
+
description: "Record which rung of the correction ladder closes a repeated correction class: structural change, lint/test/CI check, state-triggered hook, or prose with a stated reason (#810)."
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
category: management
|
|
6
|
+
skillType: claude-skill
|
|
7
|
+
assignableRoles:
|
|
8
|
+
- team-leader
|
|
9
|
+
triggers:
|
|
10
|
+
- decide correction
|
|
11
|
+
- correction ladder
|
|
12
|
+
- make it impossible
|
|
13
|
+
- add a check for this
|
|
14
|
+
tags:
|
|
15
|
+
- correction
|
|
16
|
+
- ladder
|
|
17
|
+
- quality
|
|
18
|
+
- management
|
|
19
|
+
execution:
|
|
20
|
+
type: script
|
|
21
|
+
script:
|
|
22
|
+
file: execute.sh
|
|
23
|
+
interpreter: bash
|
|
24
|
+
timeoutMs: 15000
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
# Decide Correction
|
|
28
|
+
|
|
29
|
+
The correction ladder counts corrections per **class** (a short slug such as `git-add-all`) in each project. The second time a class is recorded you receive a WorkItem: the same kind of mistake came back, and prose (memory, SOP, prompt) did not stop it. This skill records your answer and closes the ladder for that class.
|
|
30
|
+
|
|
31
|
+
## The rungs, highest first
|
|
32
|
+
|
|
33
|
+
| Rung | Meaning | Example |
|
|
34
|
+
|------|---------|---------|
|
|
35
|
+
| `structural` | Change the API, type or file layout so the mistake can no longer be expressed | the helper takes a typed enum instead of a free string |
|
|
36
|
+
| `check` | A lint rule, test or CI step fails before merge | an ESLint rule, a test that greps for `git add -A` in scripts |
|
|
37
|
+
| `hook` | A state-triggered hook or skill guard catches it the moment it happens | a pre-commit hook; a skill script that refuses the argument |
|
|
38
|
+
| `prose` | Keep it as memory/SOP text — with the reason nothing above is worth it | "happens once a quarter, the fix costs more than the mistake" |
|
|
39
|
+
|
|
40
|
+
Do the work for the rung you pick (or open the PR / ticket for it) **first**, then record the choice with the link. A `prose` decision is not final: if the class comes back twice more, the ladder raises it again and names your earlier reason.
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
bash {{SKILLS_PATH}}/team-leader/decide-correction/execute.sh \
|
|
46
|
+
--project /projects/app --class git-add-all --rung check \
|
|
47
|
+
--reason "test in scripts.test.ts fails on 'git add -A'" --link https://github.com/org/repo/pull/321
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Parameters
|
|
51
|
+
|
|
52
|
+
| Flag | JSON Field | Required | Description |
|
|
53
|
+
|------|-----------|----------|-------------|
|
|
54
|
+
| `--project` / `-p` | `projectPath` | Yes | Absolute project root the class was recorded in |
|
|
55
|
+
| `--class` / `-c` | `correctionClass` | Yes | The class slug from the WorkItem title |
|
|
56
|
+
| `--rung` / `-r` | `rung` | Yes | `structural`, `check`, `hook` or `prose` |
|
|
57
|
+
| `--reason` | `reason` | Yes | Why this rung (required for every rung) |
|
|
58
|
+
| `--link` | `link` | No | PR, file, rule or hook that implements it |
|
|
59
|
+
| `--by` | `decidedBy` | No | Your session name (default `$CREWLY_SESSION_NAME`) |
|
|
60
|
+
|
|
61
|
+
## Output
|
|
62
|
+
|
|
63
|
+
The class record: tally, occurrences, and the decision just made. To see every class of a project: `GET /api/memory/corrections?projectPath=<root>`.
|
|
64
|
+
|
|
65
|
+
The owner is not involved in ladder decisions. Never post them in the owner's thread.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Record the team lead's rung for a correction class (#810).
|
|
3
|
+
# execute.sh --project <root> --class <slug> --rung <structural|check|hook|prose> --reason '<why>' [--link <url>] [--by <session>]
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
source "${SCRIPT_DIR}/../_common/lib.sh"
|
|
7
|
+
|
|
8
|
+
INPUT_JSON=""
|
|
9
|
+
PROJECT_PATH=""
|
|
10
|
+
CLASS=""
|
|
11
|
+
RUNG=""
|
|
12
|
+
REASON=""
|
|
13
|
+
LINK=""
|
|
14
|
+
BY="${CREWLY_SESSION_NAME:-}"
|
|
15
|
+
|
|
16
|
+
if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
|
|
17
|
+
INPUT_JSON="$1"
|
|
18
|
+
shift || true
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
while [[ $# -gt 0 ]]; do
|
|
22
|
+
case "$1" in
|
|
23
|
+
--project|-p) PROJECT_PATH="$2"; shift 2 ;;
|
|
24
|
+
--class|-c) CLASS="$2"; shift 2 ;;
|
|
25
|
+
--rung|-r) RUNG="$2"; shift 2 ;;
|
|
26
|
+
--reason) REASON="$2"; shift 2 ;;
|
|
27
|
+
--link) LINK="$2"; shift 2 ;;
|
|
28
|
+
--by) BY="$2"; shift 2 ;;
|
|
29
|
+
--json|-j) INPUT_JSON="$2"; shift 2 ;;
|
|
30
|
+
--help|-h)
|
|
31
|
+
echo "Usage: execute.sh --project <root> --class <slug> --rung <structural|check|hook|prose> --reason '<why>' [--link <url>] [--by <session>]"
|
|
32
|
+
exit 0
|
|
33
|
+
;;
|
|
34
|
+
*) unknown_arg_exit "$1" ;;
|
|
35
|
+
esac
|
|
36
|
+
done
|
|
37
|
+
|
|
38
|
+
if [ -n "$INPUT_JSON" ]; then
|
|
39
|
+
INPUT=$(read_json_input "$INPUT_JSON")
|
|
40
|
+
[ -z "$PROJECT_PATH" ] && PROJECT_PATH=$(printf '%s' "$INPUT" | jq -r '.projectPath // empty')
|
|
41
|
+
[ -z "$CLASS" ] && CLASS=$(printf '%s' "$INPUT" | jq -r '.correctionClass // empty')
|
|
42
|
+
[ -z "$RUNG" ] && RUNG=$(printf '%s' "$INPUT" | jq -r '.rung // empty')
|
|
43
|
+
[ -z "$REASON" ] && REASON=$(printf '%s' "$INPUT" | jq -r '.reason // empty')
|
|
44
|
+
[ -z "$LINK" ] && LINK=$(printf '%s' "$INPUT" | jq -r '.link // empty')
|
|
45
|
+
[ -z "$BY" ] && BY=$(printf '%s' "$INPUT" | jq -r '.decidedBy // empty')
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
require_param "projectPath (--project)" "$PROJECT_PATH"
|
|
49
|
+
require_param "correctionClass (--class)" "$CLASS"
|
|
50
|
+
require_param "rung (--rung)" "$RUNG"
|
|
51
|
+
require_param "reason (--reason)" "$REASON"
|
|
52
|
+
[ -z "$BY" ] && BY="team-leader"
|
|
53
|
+
|
|
54
|
+
case "$RUNG" in
|
|
55
|
+
structural|check|hook|prose) ;;
|
|
56
|
+
*) error_exit "rung must be one of structural, check, hook, prose (got: $RUNG)" ;;
|
|
57
|
+
esac
|
|
58
|
+
|
|
59
|
+
export _DC_PROJECT="$PROJECT_PATH" _DC_RUNG="$RUNG" _DC_REASON="$REASON" _DC_LINK="$LINK" _DC_BY="$BY"
|
|
60
|
+
BODY=$(jq -n '{projectPath: env._DC_PROJECT, rung: env._DC_RUNG, reason: env._DC_REASON, decidedBy: env._DC_BY} + (if env._DC_LINK != "" then {link: env._DC_LINK} else {} end)')
|
|
61
|
+
unset _DC_PROJECT _DC_RUNG _DC_REASON _DC_LINK _DC_BY
|
|
62
|
+
|
|
63
|
+
api_call POST "/memory/corrections/$(printf '%s' "$CLASS" | jq -sRr @uri | tr -d '\n')/decide" "$BODY"
|
|
@@ -50,6 +50,7 @@ bash {{SKILLS_PATH}}/team-leader/handle-failure/execute.sh '{"workerId":"worker-
|
|
|
50
50
|
| `teamId` | No | Team ID (needed for reassignment lookup) |
|
|
51
51
|
| `requiredRole` | No | Role required for the task (helps find alternatives) |
|
|
52
52
|
| `taskDescription` | No | Brief task description for context |
|
|
53
|
+
| `projectPath` | No | Project root; with `failureInfo.correctionClass`, the failure is counted on the project's correction ladder (#810) |
|
|
53
54
|
| `failureInfo` | Yes | Failure details object (see below) |
|
|
54
55
|
|
|
55
56
|
### failureInfo Object
|
|
@@ -60,6 +61,7 @@ bash {{SKILLS_PATH}}/team-leader/handle-failure/execute.sh '{"workerId":"worker-
|
|
|
60
61
|
| `failedSteps` | Array of failed verification step names |
|
|
61
62
|
| `retries` | Number of retries already attempted |
|
|
62
63
|
| `failureType` | Category of failure (see below) |
|
|
64
|
+
| `correctionClass` | Optional. A short slug for the *kind* of mistake behind the failure (`skip-tests-before-pr`, `git-add-all`). Give one when the failure was a correction of how the worker works, not a flaky environment. The second time a class is recorded in a project you (the lead) get one WorkItem asking whether it can be made impossible, caught by a check or a hook, or must stay prose — answered with `decide-correction`. The output carries `correction: { class, count, raised }`. |
|
|
63
65
|
|
|
64
66
|
### Failure Types
|
|
65
67
|
|
|
@@ -19,6 +19,11 @@ RETRIES=$(printf '%s' "$INPUT" | jq -r '.failureInfo.retries // 0')
|
|
|
19
19
|
FAILURE_TYPE=$(printf '%s' "$INPUT" | jq -r '.failureInfo.failureType // "unknown"')
|
|
20
20
|
ERROR_MSG=$(printf '%s' "$INPUT" | jq -r '.failureInfo.error // "Unknown error"')
|
|
21
21
|
FAILED_STEPS=$(printf '%s' "$INPUT" | jq -c '.failureInfo.failedSteps // []')
|
|
22
|
+
# Correction ladder (#810): a classed failure is counted per project; the
|
|
23
|
+
# second occurrence of a class sends this lead a WorkItem asking for a check
|
|
24
|
+
# in code instead of another retry note.
|
|
25
|
+
CORRECTION_CLASS=$(printf '%s' "$INPUT" | jq -r '.failureInfo.correctionClass // empty')
|
|
26
|
+
PROJECT_PATH=$(printf '%s' "$INPUT" | jq -r '.projectPath // empty')
|
|
22
27
|
|
|
23
28
|
require_param "workerId" "$WORKER_ID"
|
|
24
29
|
|
|
@@ -97,6 +102,17 @@ if [ "$ACTION" = "reassign" ] && [ -n "$TEAM_ID" ]; then
|
|
|
97
102
|
fi
|
|
98
103
|
fi
|
|
99
104
|
|
|
105
|
+
# Correction ladder (#810): count the classed failure; the answer says whether
|
|
106
|
+
# this occurrence raised the ladder WorkItem. Never fails the decision.
|
|
107
|
+
CORRECTION_JSON="null"
|
|
108
|
+
if [ -n "$CORRECTION_CLASS" ] && [ -n "$PROJECT_PATH" ]; then
|
|
109
|
+
export _HF_PROJECT="$PROJECT_PATH" _HF_CLASS="$CORRECTION_CLASS" _HF_AGENT="${WORKER_SESSION:-$WORKER_ID}" _HF_TEXT="$ERROR_MSG" _HF_TASK="$TASK_DESCRIPTION"
|
|
110
|
+
CORR_BODY=$(jq -n '{projectPath: env._HF_PROJECT, correctionClass: env._HF_CLASS, agentId: env._HF_AGENT, text: env._HF_TEXT, source: "failure"} + (if env._HF_TASK != "" then {relatedTask: env._HF_TASK} else {} end)')
|
|
111
|
+
unset _HF_PROJECT _HF_CLASS _HF_AGENT _HF_TEXT _HF_TASK
|
|
112
|
+
CORRECTION_JSON=$( (api_call POST "/memory/corrections" "$CORR_BODY" 2>/dev/null || true) | jq -c '.data // null' 2>/dev/null || true)
|
|
113
|
+
[ -z "$CORRECTION_JSON" ] && CORRECTION_JSON="null"
|
|
114
|
+
fi
|
|
115
|
+
|
|
100
116
|
# Output decision
|
|
101
117
|
jq -n \
|
|
102
118
|
--arg action "$ACTION" \
|
|
@@ -106,8 +122,10 @@ jq -n \
|
|
|
106
122
|
--arg originalWorkerId "$WORKER_ID" \
|
|
107
123
|
--arg failureType "$FAILURE_TYPE" \
|
|
108
124
|
--arg retries "$RETRIES" \
|
|
125
|
+
--argjson correction "$CORRECTION_JSON" \
|
|
109
126
|
'{
|
|
110
127
|
action: $action,
|
|
128
|
+
correction: $correction,
|
|
111
129
|
nextWorkerId: (if $nextWorkerId != "" then $nextWorkerId else null end),
|
|
112
130
|
nextWorkerSession: (if $nextWorkerSession != "" then $nextWorkerSession else null end),
|
|
113
131
|
instructions: $instructions,
|
|
@@ -152,6 +152,16 @@ export declare const TICKET_AUTOPILOT_CONSTANTS: {
|
|
|
152
152
|
/** Option labels of that card */
|
|
153
153
|
readonly RETRO_APPROVE_LABEL: "Approve";
|
|
154
154
|
readonly RETRO_SKIP_LABEL: "Skip";
|
|
155
|
+
/** `metadata.kind` of the weekly retro WorkItem (same WorkItem type as the daily retro) */
|
|
156
|
+
readonly WEEKLY_RETRO_METADATA_KIND: "autopilot_weekly_retro";
|
|
157
|
+
/** Local weekday (0 = Sunday) on or after which, at RETRO_HOUR_LOCAL, the previous ISO week's retro is scheduled */
|
|
158
|
+
readonly WEEKLY_RETRO_WEEKDAY_LOCAL: 1;
|
|
159
|
+
/** Global-vault folder the weekly retros are written to */
|
|
160
|
+
readonly WEEKLY_RETRO_WIKI_DIR: "llm-curated/autopilot-retros/weekly";
|
|
161
|
+
/** Most projects listed in detail in the weekly brief (the rest are counted) */
|
|
162
|
+
readonly WEEKLY_RETRO_MAX_PROJECTS_IN_BRIEF: 12;
|
|
163
|
+
/** How long filed daily retros are remembered (days) — the weekly retro reads them */
|
|
164
|
+
readonly RETRO_FILED_MEMORY_DAYS: 60;
|
|
155
165
|
/** WorkItem type / `metadata.kind` of the goal replan the driver receives when nothing is left to triage */
|
|
156
166
|
readonly REPLAN_WORK_ITEM_TYPE: "goal_replan";
|
|
157
167
|
readonly REPLAN_METADATA_KIND: "goal_replan";
|
|
@@ -2181,6 +2191,31 @@ export declare const WIKI_GAPS_CONSTANTS: {
|
|
|
2181
2191
|
/** Session that authors the page. */
|
|
2182
2192
|
readonly CALLER_SESSION: "system:wiki-knowledge-gaps";
|
|
2183
2193
|
};
|
|
2194
|
+
/**
|
|
2195
|
+
* Correction ladder (#810): repeated corrections of one class become a
|
|
2196
|
+
* team-lead WorkItem asking for a check in code instead of more prose.
|
|
2197
|
+
*/
|
|
2198
|
+
export declare const CORRECTION_LADDER_CONSTANTS: {
|
|
2199
|
+
/** Per-project store, under the project data dir */
|
|
2200
|
+
readonly STORE_FILE: "correction-ladder.json";
|
|
2201
|
+
/** Occurrences of a class (or after a prose decision) that raise the lead's WorkItem */
|
|
2202
|
+
readonly THRESHOLD: 2;
|
|
2203
|
+
/** An undecided WorkItem older than this is treated as abandoned and raised again */
|
|
2204
|
+
readonly REOPEN_AFTER_MS: number;
|
|
2205
|
+
/** The rungs, highest first: make it impossible → catch before merge → catch when it happens → tell them again */
|
|
2206
|
+
readonly RUNGS: readonly ["structural", "check", "hook", "prose"];
|
|
2207
|
+
/** Class slug bounds */
|
|
2208
|
+
readonly CLASS_MIN_CHARS: 2;
|
|
2209
|
+
readonly CLASS_MAX_CHARS: 48;
|
|
2210
|
+
/** Occurrences kept per class (newest) */
|
|
2211
|
+
readonly MAX_OCCURRENCES_KEPT: 20;
|
|
2212
|
+
/** Occurrences quoted in the lead's brief */
|
|
2213
|
+
readonly OCCURRENCES_IN_BRIEF: 5;
|
|
2214
|
+
/** Correction text kept per occurrence */
|
|
2215
|
+
readonly OCCURRENCE_TEXT_MAX_CHARS: 400;
|
|
2216
|
+
/** WorkItem `metadata.kind` */
|
|
2217
|
+
readonly WORKITEM_KIND: "correction-ladder";
|
|
2218
|
+
};
|
|
2184
2219
|
/**
|
|
2185
2220
|
* Daily agent-memory refresh (#1345): what an agent recorded in the wiki
|
|
2186
2221
|
* log is reflected into its `memory.json` and the project's memory.
|