@jenga-ai/agent 3.6.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -1
- package/lib/generate-skill-allow-list.js +42 -5
- package/lib/skill-allow-list.json +1 -1
- package/package.json +1 -2
- package/project/app/api/lib/resolve-project-root.js +1 -1
- package/project/app/api/scripts/capture-snapshot.js +12 -7
- package/project/app/package.json +4 -0
- package/project/app/ui/dist/assets/index-BADc5mmH.css +1 -0
- package/project/app/ui/dist/assets/index-DX2pfTAW.js +104 -0
- package/project/app/ui/dist/index.html +2 -2
- package/scripts/acquire-concurrency-slot.sh +34 -4
- package/scripts/apply-j-prefix.sh +1 -1
- package/scripts/delete-bare-skill-dirs.sh +1 -2
- package/scripts/idea_manager.sh +16 -1
- package/scripts/release-concurrency-slot.sh +34 -4
- package/scripts/render-ranked-list.sh +270 -0
- package/scripts/repoint-dead-bare-path-prose.py +81 -0
- package/scripts/rewrite-stale-skill-preambles.py +188 -0
- package/scripts/strip-polyfill-frontmatter.py +166 -0
- package/scripts/todo_manager.sh +16 -1
- package/scripts/validate-typed-object.sh +750 -0
- package/scripts/verify-postinstall-reconcile.sh +33 -7
- package/skills/index/scripts/board_index.py +29 -1
- package/skills/j-brainstorm/SKILL.md +3 -4
- package/skills/j-btw/SKILL.md +3 -4
- package/skills/j-clearify/SKILL.md +3 -4
- package/skills/j-close-story/SKILL.md +11 -12
- package/skills/j-close-story/scripts/check-story-closeable.sh +11 -4
- package/skills/j-commit/SKILL.md +3 -4
- package/skills/j-continue/SKILL.md +5 -6
- package/skills/j-deep-dive/SKILL.md +3 -4
- package/skills/j-distribute/SKILL.md +3 -4
- package/skills/j-do/SKILL.md +13 -15
- package/skills/j-doc/SKILL.md +3 -4
- package/skills/j-doc/scripts/resolve_last_update.py +27 -1
- package/skills/j-doc-sync/SKILL.md +3 -4
- package/skills/j-dooo/SKILL.md +6 -15
- package/skills/j-error/SKILL.md +3 -4
- package/skills/j-evaluate/SKILL.md +3 -4
- package/skills/j-examplify/SKILL.md +3 -4
- package/skills/j-help/SKILL.md +3 -4
- package/skills/j-idea/SKILL.md +3 -4
- package/skills/j-improve/SKILL.md +3 -4
- package/skills/j-init/SKILL.md +20 -11
- package/skills/j-init/scripts/apply-scaffold-visibility.sh +8 -6
- package/skills/j-jbp/SKILL.md +3 -4
- package/skills/j-lgtm/SKILL.md +3 -4
- package/skills/j-pi-plan/SKILL.md +3 -4
- package/skills/j-proceed/SKILL.md +3 -4
- package/skills/j-publish/SKILL.md +3 -4
- package/skills/j-publish/scripts/run_gates.sh +1 -1
- package/skills/j-reconcile/SKILL.md +38 -5
- package/skills/j-reconcile/assets/report_format.md +11 -0
- package/skills/j-reconcile/scripts/detect-unlinked-code.sh +2 -2
- package/skills/j-reconcile-origin/SKILL.md +3 -4
- package/skills/j-redo/SKILL.md +3 -4
- package/skills/j-skillify/SKILL.md +3 -4
- package/skills/j-spinoff/SKILL.md +3 -4
- package/skills/j-status/SKILL.md +4 -5
- package/skills/j-todo/SKILL.md +42 -5
- package/skills/j-todo/scripts/add_trivial_task.sh +12 -1
- package/skills/j-todo/scripts/argument-is-not-ranked-list.sh +92 -0
- package/skills/j-todo/scripts/argument-is-ranked-list.sh +78 -0
- package/skills/j-uncharted/SKILL.md +251 -12
- package/skills/j-uncharted/scripts/detect-dependencies.sh +79 -21
- package/skills/j-uncharted/scripts/diff-since-baseline.sh +600 -0
- package/skills/j-uncharted/scripts/find-scan-baseline.sh +545 -0
- package/skills/j-uncharted/scripts/run-engine.sh +36 -2
- package/skills/j-uncharted/scripts/write-scan-record.sh +361 -0
- package/skills/j-wtf/SKILL.md +3 -4
- package/skills/jenga/SKILL.md +106 -10
- package/skills/jenga/playbooks/schema.json +4 -4
- package/skills/jenga/scripts/enrich-nl-prompt.sh +225 -0
- package/skills/jenga/scripts/load-nl-catalog.js +6 -3
- package/skills/jenga/scripts/load-playbooks.sh +289 -4
- package/skills/jenga/scripts/match-playbook.sh +6 -5
- package/skills/jenga/scripts/run-playbook-step.sh +270 -3
- package/templates/permission-levels/level-1-locked.json +1 -1
- package/templates/permission-levels/level-2-guarded.json +1 -1
- package/templates/permission-levels/level-3-standard.json +1 -1
- package/templates/permission-levels/level-4-elevated.json +1 -1
- package/templates/permission-levels/level-5-unrestricted.json +1 -1
- package/templates/playbook-types.json +6 -0
- package/project/app/ui/dist/assets/index-BVR_7Owg.css +0 -1
- package/project/app/ui/dist/assets/index-CtU2xLQm.js +0 -104
- package/scripts/audit-twin-divergence.sh +0 -693
|
@@ -330,13 +330,27 @@ run_install "$PKG2C" "$CONSUMER_C" "$FIXTURE/case-v2.log"
|
|
|
330
330
|
|
|
331
331
|
# Detect whether this filesystem is even case-insensitive; on a case-SENSITIVE fs
|
|
332
332
|
# both names legitimately coexist and the old one is genuinely stale.
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
333
|
+
#
|
|
334
|
+
# This probes the filesystem DIRECTLY rather than inferring the answer from the
|
|
335
|
+
# mirrored tree. The previous inference was circular -- it asked whether both
|
|
336
|
+
# skill.md and SKILL.md exist with DIFFERENT content, but both fixture packages
|
|
337
|
+
# above write the identical body ("# alpha"), so the inequality was false by
|
|
338
|
+
# construction and the branch concluded "case-insensitive" on every filesystem.
|
|
339
|
+
# On macOS that happened to be the right answer; on a case-SENSITIVE fs (any
|
|
340
|
+
# Linux CI runner) it was wrong, and the case-insensitive branch below then ran
|
|
341
|
+
# an assert_grep for "written-this-run" that can only hold when the two names
|
|
342
|
+
# collide -- recording a FAIL that no individual @test asserts, so only
|
|
343
|
+
# "harness reports zero failures overall" caught it. Surfaced by the E28_S17
|
|
344
|
+
# mirror staging gate's first Linux runs (2026-09-28).
|
|
345
|
+
CASE_PROBE="$FIXTURE/case-probe"
|
|
346
|
+
mkdir -p "$CASE_PROBE"
|
|
347
|
+
: > "$CASE_PROBE/probe"
|
|
348
|
+
if [ -e "$CASE_PROBE/PROBE" ]; then
|
|
338
349
|
CASE_INSENSITIVE=1
|
|
350
|
+
else
|
|
351
|
+
CASE_INSENSITIVE=0
|
|
339
352
|
fi
|
|
353
|
+
rm -rf "$CASE_PROBE"
|
|
340
354
|
|
|
341
355
|
if [ "$CASE_INSENSITIVE" -eq 1 ]; then
|
|
342
356
|
# The whole point: the skill must still exist under SOME name after the upgrade.
|
|
@@ -353,8 +367,20 @@ if [ "$CASE_INSENSITIVE" -eq 1 ]; then
|
|
|
353
367
|
assert_grep "written-this-run" "$FIXTURE/case-v2.log" \
|
|
354
368
|
"identity guard reports the spared entry as written-this-run"
|
|
355
369
|
else
|
|
356
|
-
|
|
357
|
-
|
|
370
|
+
# These names must remain PREFIX-COMPATIBLE with the case-insensitive branch
|
|
371
|
+
# above: assert_check in tests/postinstall-delete-reconciliation.bats matches
|
|
372
|
+
# with grep -F on "<tab><name>", a substring match, so a trailing "(n/a ...)"
|
|
373
|
+
# qualifier still satisfies an assertion written against the canonical name
|
|
374
|
+
# while keeping the skip visible in the harness output. The identity-guard
|
|
375
|
+
# line below already followed this convention; the two case-only-rename lines
|
|
376
|
+
# did not -- they were renamed wholesale to "case-only rename (skipped: ...)",
|
|
377
|
+
# which shares no prefix with the canonical name, so on a case-sensitive fs
|
|
378
|
+
# the "case-only rename does not delete the file the run just wrote" @test
|
|
379
|
+
# would fail with "no such check recorded by the harness". That never fired
|
|
380
|
+
# before only because the broken detection above forced every filesystem down
|
|
381
|
+
# the case-insensitive branch.
|
|
382
|
+
pass "case-only rename does not delete the just-written file (.agents) (n/a: filesystem is case-sensitive, both names legitimately coexist)"
|
|
383
|
+
pass "case-only rename does not delete the just-written file (.claude) (n/a: filesystem is case-sensitive, both names legitimately coexist)"
|
|
358
384
|
pass "identity guard reports the spared entry as written-this-run (n/a on case-sensitive fs)"
|
|
359
385
|
fi
|
|
360
386
|
|
|
@@ -6,6 +6,7 @@ import argparse
|
|
|
6
6
|
import hashlib
|
|
7
7
|
import json
|
|
8
8
|
import re
|
|
9
|
+
import subprocess
|
|
9
10
|
import sys
|
|
10
11
|
from pathlib import Path
|
|
11
12
|
from typing import Any
|
|
@@ -33,7 +34,34 @@ EDGE_TYPES = {
|
|
|
33
34
|
"parent_doc",
|
|
34
35
|
}
|
|
35
36
|
FRONTMATTER_BOUNDARY = "---"
|
|
36
|
-
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _resolve_project_root() -> Path:
|
|
40
|
+
"""Locate the project root via git, not a fixed relative climb.
|
|
41
|
+
|
|
42
|
+
This script is deployed both at its source location
|
|
43
|
+
(skills/index/scripts/) and mirrored one directory deeper into
|
|
44
|
+
.claude/skills/index/scripts/ / .agents/skills/index/scripts/ -- a fixed
|
|
45
|
+
parents[N] climb from __file__ only lands on the real repo root from the
|
|
46
|
+
source location, not from a mirror. Same approach as
|
|
47
|
+
skills/j-close-story/scripts/check-story-closeable.sh,
|
|
48
|
+
check-privatized.sh:138, and compute-scope-divergence.sh:54 use for the
|
|
49
|
+
equivalent bash case.
|
|
50
|
+
"""
|
|
51
|
+
try:
|
|
52
|
+
result = subprocess.run(
|
|
53
|
+
["git", "rev-parse", "--show-toplevel"],
|
|
54
|
+
cwd=Path(__file__).resolve().parent,
|
|
55
|
+
capture_output=True,
|
|
56
|
+
text=True,
|
|
57
|
+
check=True,
|
|
58
|
+
)
|
|
59
|
+
return Path(result.stdout.strip())
|
|
60
|
+
except (subprocess.CalledProcessError, FileNotFoundError, OSError):
|
|
61
|
+
return Path.cwd()
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
ROOT_DIR = _resolve_project_root()
|
|
37
65
|
BOARD_ID_RE = re.compile(r"^E\d{2}(?:_S\d{2})?(?:_T\d{2})?$")
|
|
38
66
|
PLAN_RE = re.compile(r"^(E\d{2}_S\d{2}(?:_T\d{2})?)-plan$")
|
|
39
67
|
SUMMARY_RE = re.compile(r"^(E\d{2}_S\d{2}(?:_T\d{2})?)-summary$")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: j.brainstorm
|
|
3
|
-
description:
|
|
3
|
+
description: Engage the scrum-master agent in a focused planning session to define, refine, or challenge features, improvements, tasks, stories, and epics. The agent asks probing questions, challenges assumptions, and helps shape ideas into actionable backlog items.
|
|
4
4
|
keywords:
|
|
5
5
|
- brainstorm
|
|
6
6
|
- plan
|
|
@@ -8,7 +8,6 @@ keywords:
|
|
|
8
8
|
- feature planning
|
|
9
9
|
- requirements
|
|
10
10
|
- j-brainstorm
|
|
11
|
-
- polyfill
|
|
12
11
|
examples:
|
|
13
12
|
- "let's brainstorm ideas for X"
|
|
14
13
|
- "I need to plan a new feature"
|
|
@@ -19,9 +18,9 @@ metadata:
|
|
|
19
18
|
|
|
20
19
|
# Brainstorm — Collaborative Planning with the Scrum Master
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
`skills/j-brainstorm/` is the **canonical, hand-edited** directory for this skill, per CLAUDE.md's "The Canonical Naming Contract" (the `E50` reopening of 2026-09-09, which promoted `skills/j-brainstorm/` from generated twin to sole canonical form). The `j-` prefix is there for collision safety — a real directory under a distinct name, so a host tool shipping its own same-named built-in command cannot shadow it (Claude Code's native skill resolution is a literal-string, directory-name-based match; see `docs/skill-authoring.md`'s "Invocation Convention").
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
> ⚠️ **`scripts/generate-j-alias.sh` was retired by `E50_S14` and no longer exists — there is nothing to run.** This file was previously generated from a bare `skills/brainstorm/SKILL.md` source; `E50_S15` deleted that directory. This file is now the sole canonical, hand-edited source for this skill — edit it directly.
|
|
25
24
|
|
|
26
25
|
## Instructions
|
|
27
26
|
|
package/skills/j-btw/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: j.btw
|
|
3
|
-
description:
|
|
3
|
+
description: Capture a new mission (feature, change, or addition) and fit it into the project's Epic/Story structure, then choose to implement now or defer.
|
|
4
4
|
keywords:
|
|
5
5
|
- btw
|
|
6
6
|
- capture
|
|
@@ -8,7 +8,6 @@ keywords:
|
|
|
8
8
|
- new idea
|
|
9
9
|
- side task
|
|
10
10
|
- j-btw
|
|
11
|
-
- polyfill
|
|
12
11
|
examples:
|
|
13
12
|
- "btw I also need to add X"
|
|
14
13
|
- "capture this as a new task"
|
|
@@ -19,9 +18,9 @@ metadata:
|
|
|
19
18
|
|
|
20
19
|
# BTW — Capture a Mission
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
`skills/j-btw/` is the **canonical, hand-edited** directory for this skill, per CLAUDE.md's "The Canonical Naming Contract" (the `E50` reopening of 2026-09-09, which promoted `skills/j-btw/` from generated twin to sole canonical form). The `j-` prefix is there for collision safety — a real directory under a distinct name, so a host tool shipping its own same-named built-in command cannot shadow it (Claude Code's native skill resolution is a literal-string, directory-name-based match; see `docs/skill-authoring.md`'s "Invocation Convention").
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
> ⚠️ **`scripts/generate-j-alias.sh` was retired by `E50_S14` and no longer exists — there is nothing to run.** This file was previously generated from a bare `skills/btw/SKILL.md` source; `E50_S15` deleted that directory. This file is now the sole canonical, hand-edited source for this skill — edit it directly.
|
|
25
24
|
|
|
26
25
|
## Instructions
|
|
27
26
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: j.clearify
|
|
3
|
-
description:
|
|
3
|
+
description: Clarifies ambiguous, dense, or under-specified prompts and conversation on request — inspects an attached prompt or falls back to the current conversation and surfaces plain-language clarifications with examples.
|
|
4
4
|
keywords:
|
|
5
5
|
- clarify this
|
|
6
6
|
- clarify
|
|
@@ -10,7 +10,6 @@ keywords:
|
|
|
10
10
|
- explain that again
|
|
11
11
|
- can you simplify
|
|
12
12
|
- j-clearify
|
|
13
|
-
- polyfill
|
|
14
13
|
examples:
|
|
15
14
|
- "clarify this"
|
|
16
15
|
- "clearify the last message"
|
|
@@ -22,9 +21,9 @@ alias: wtf
|
|
|
22
21
|
|
|
23
22
|
# Clearify — Ambiguity Clarification
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
`skills/j-clearify/` is the **canonical, hand-edited** directory for this skill, per CLAUDE.md's "The Canonical Naming Contract" (the `E50` reopening of 2026-09-09, which promoted `skills/j-clearify/` from generated twin to sole canonical form). The `j-` prefix is there for collision safety — a real directory under a distinct name, so a host tool shipping its own same-named built-in command cannot shadow it (Claude Code's native skill resolution is a literal-string, directory-name-based match; see `docs/skill-authoring.md`'s "Invocation Convention").
|
|
26
25
|
|
|
27
|
-
|
|
26
|
+
> ⚠️ **`scripts/generate-j-alias.sh` was retired by `E50_S14` and no longer exists — there is nothing to run.** This file was previously generated from a bare `skills/clearify/SKILL.md` source; `E50_S15` deleted that directory. This file is now the sole canonical, hand-edited source for this skill — edit it directly.
|
|
28
27
|
|
|
29
28
|
> **Note on the `alias: wtf` frontmatter field:** this repo has no runtime mechanism that reads an `alias` key to route slash commands — no existing `SKILL.md` implements one, and `project/configs/workflow.json` has no alias registry. The field here documents the intended relationship only. `/wtf` is made invocable as a working alias by the companion skill folder at `skills/j-wtf/SKILL.md`, which delegates to these same instructions.
|
|
30
29
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: j.close-story
|
|
3
|
-
description:
|
|
3
|
+
description: Close a story by verifying all tasks are in terminal state, extracting actual diff stats per task, computing scope divergence flags, and writing closure metadata to task frontmatter.
|
|
4
4
|
keywords:
|
|
5
5
|
- close story
|
|
6
6
|
- close
|
|
@@ -8,7 +8,6 @@ keywords:
|
|
|
8
8
|
- complete story
|
|
9
9
|
- story done
|
|
10
10
|
- j-close-story
|
|
11
|
-
- polyfill
|
|
12
11
|
examples:
|
|
13
12
|
- "close story E17_S06"
|
|
14
13
|
- "/close-story E32_S06"
|
|
@@ -18,9 +17,9 @@ examples:
|
|
|
18
17
|
|
|
19
18
|
# close-story — Close a Story
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
`skills/j-close-story/` is the **canonical, hand-edited** directory for this skill, per CLAUDE.md's "The Canonical Naming Contract" (the `E50` reopening of 2026-09-09, which promoted `skills/j-close-story/` from generated twin to sole canonical form). The `j-` prefix is there for collision safety — a real directory under a distinct name, so a host tool shipping its own same-named built-in command cannot shadow it (Claude Code's native skill resolution is a literal-string, directory-name-based match; see `docs/skill-authoring.md`'s "Invocation Convention").
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
> ⚠️ **`scripts/generate-j-alias.sh` was retired by `E50_S14` and no longer exists — there is nothing to run.** This file was previously generated from a bare `skills/close-story/SKILL.md` source; `E50_S15` deleted that directory. This file is now the sole canonical, hand-edited source for this skill — edit it directly.
|
|
24
23
|
|
|
25
24
|
## Purpose
|
|
26
25
|
|
|
@@ -45,7 +44,7 @@ This file is generated/synced by `scripts/generate-j-alias.sh close-story` from
|
|
|
45
44
|
Run the guard script:
|
|
46
45
|
|
|
47
46
|
```bash
|
|
48
|
-
bash skills/j-close-story/scripts/check-story-closeable.sh <story-id>
|
|
47
|
+
bash "$([ -f skills/j-close-story/scripts/check-story-closeable.sh ] && echo skills/j-close-story/scripts/check-story-closeable.sh || echo node_modules/@jenga-ai/agent/skills/j-close-story/scripts/check-story-closeable.sh)" <story-id>
|
|
49
48
|
```
|
|
50
49
|
|
|
51
50
|
- If it exits with code 0 and prints `CLOSEABLE`, continue.
|
|
@@ -72,7 +71,7 @@ For **each task ID** listed in the story's `tasks:` frontmatter array:
|
|
|
72
71
|
|
|
73
72
|
3. **Run per-task diff stat extraction:**
|
|
74
73
|
```bash
|
|
75
|
-
bash skills/j-close-story/scripts/extract-task-diff-stats.sh <task-id>
|
|
74
|
+
bash "$([ -f skills/j-close-story/scripts/extract-task-diff-stats.sh ] && echo skills/j-close-story/scripts/extract-task-diff-stats.sh || echo node_modules/@jenga-ai/agent/skills/j-close-story/scripts/extract-task-diff-stats.sh)" <task-id>
|
|
76
75
|
```
|
|
77
76
|
The script outputs:
|
|
78
77
|
```
|
|
@@ -83,11 +82,11 @@ For **each task ID** listed in the story's `tasks:` frontmatter array:
|
|
|
83
82
|
|
|
84
83
|
4. **Write stats to task frontmatter:**
|
|
85
84
|
```bash
|
|
86
|
-
bash skills/j-close-story/scripts/update-task-frontmatter.sh \
|
|
85
|
+
bash "$([ -f skills/j-close-story/scripts/update-task-frontmatter.sh ] && echo skills/j-close-story/scripts/update-task-frontmatter.sh || echo node_modules/@jenga-ai/agent/skills/j-close-story/scripts/update-task-frontmatter.sh)" \
|
|
87
86
|
"project/board/tasks/<task-id>_*.md" \
|
|
88
87
|
actual_files_changed <N>
|
|
89
88
|
|
|
90
|
-
bash skills/j-close-story/scripts/update-task-frontmatter.sh \
|
|
89
|
+
bash "$([ -f skills/j-close-story/scripts/update-task-frontmatter.sh ] && echo skills/j-close-story/scripts/update-task-frontmatter.sh || echo node_modules/@jenga-ai/agent/skills/j-close-story/scripts/update-task-frontmatter.sh)" \
|
|
91
90
|
"project/board/tasks/<task-id>_*.md" \
|
|
92
91
|
actual_lines_delta <N>
|
|
93
92
|
```
|
|
@@ -104,13 +103,13 @@ For **each task ID** listed in the story's `tasks:` frontmatter array:
|
|
|
104
103
|
|
|
105
104
|
Run the divergence computation:
|
|
106
105
|
```bash
|
|
107
|
-
DIVERGENCE_FLAG=$(bash skills/j-close-story/scripts/compute-scope-divergence.sh \
|
|
106
|
+
DIVERGENCE_FLAG=$(bash "$([ -f skills/j-close-story/scripts/compute-scope-divergence.sh ] && echo skills/j-close-story/scripts/compute-scope-divergence.sh || echo node_modules/@jenga-ai/agent/skills/j-close-story/scripts/compute-scope-divergence.sh)" \
|
|
108
107
|
"<execution_scope>" <actual_files_changed> <actual_lines_delta>)
|
|
109
108
|
```
|
|
110
109
|
|
|
111
110
|
Write the result to task frontmatter:
|
|
112
111
|
```bash
|
|
113
|
-
bash skills/j-close-story/scripts/update-task-frontmatter.sh \
|
|
112
|
+
bash "$([ -f skills/j-close-story/scripts/update-task-frontmatter.sh ] && echo skills/j-close-story/scripts/update-task-frontmatter.sh || echo node_modules/@jenga-ai/agent/skills/j-close-story/scripts/update-task-frontmatter.sh)" \
|
|
114
113
|
"project/board/tasks/<task-id>_*.md" \
|
|
115
114
|
scope_divergence_flag "$DIVERGENCE_FLAG"
|
|
116
115
|
```
|
|
@@ -127,7 +126,7 @@ For **each task ID** listed in the story's `tasks:` frontmatter array:
|
|
|
127
126
|
frontmatter writes and divergence computation above, check whether this
|
|
128
127
|
task's own work is permanently excluded from the public mirror:
|
|
129
128
|
```bash
|
|
130
|
-
bash skills/j-close-story/scripts/check-privatized.sh <task-id> "project/board/tasks/<task-id>_*.md"
|
|
129
|
+
bash "$([ -f skills/j-close-story/scripts/check-privatized.sh ] && echo skills/j-close-story/scripts/check-privatized.sh || echo node_modules/@jenga-ai/agent/skills/j-close-story/scripts/check-privatized.sh)" <task-id> "project/board/tasks/<task-id>_*.md"
|
|
131
130
|
```
|
|
132
131
|
This is a **static** check (per `$([ -f templates/SCRUM_BOARD_SCHEMA.md ] && echo templates/SCRUM_BOARD_SCHEMA.md || echo node_modules/@jenga-ai/agent/templates/SCRUM_BOARD_SCHEMA.md)`'s "Static
|
|
133
132
|
vs. Reactive Status Setting" section) — it derives the task's touched-file
|
|
@@ -177,7 +176,7 @@ against the story's own direct commits (E51_S03_T03) **before** deciding the
|
|
|
177
176
|
story's terminal status:
|
|
178
177
|
|
|
179
178
|
```bash
|
|
180
|
-
bash skills/j-close-story/scripts/check-privatized.sh <story-id> "project/board/stories/<story-id>_*.md"
|
|
179
|
+
bash "$([ -f skills/j-close-story/scripts/check-privatized.sh ] && echo skills/j-close-story/scripts/check-privatized.sh || echo node_modules/@jenga-ai/agent/skills/j-close-story/scripts/check-privatized.sh)" <story-id> "project/board/stories/<story-id>_*.md"
|
|
181
180
|
```
|
|
182
181
|
|
|
183
182
|
Passing the story id (`E##_S##`) rather than a task id makes the script's
|
|
@@ -21,11 +21,18 @@ usage() {
|
|
|
21
21
|
exit 1
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
# Locate the project root relative
|
|
25
|
-
#
|
|
26
|
-
#
|
|
24
|
+
# Locate the project root via git, not a fixed relative climb — this script
|
|
25
|
+
# is deployed both at its source location (skills/j-close-story/scripts/)
|
|
26
|
+
# and mirrored to .claude/skills/j-close-story/scripts/, and a fixed "three
|
|
27
|
+
# levels up" climb lands in the wrong place from the mirror. Same approach as
|
|
28
|
+
# this directory's siblings: check-privatized.sh:138 and
|
|
29
|
+
# compute-scope-divergence.sh:54.
|
|
27
30
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
28
|
-
PROJECT_ROOT="$(
|
|
31
|
+
PROJECT_ROOT="$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel 2>/dev/null || true)"
|
|
32
|
+
if [[ -z "$PROJECT_ROOT" ]]; then
|
|
33
|
+
echo "ERROR: could not locate project root (git rev-parse --show-toplevel failed from $SCRIPT_DIR)" >&2
|
|
34
|
+
exit 1
|
|
35
|
+
fi
|
|
29
36
|
STORIES_DIR="$PROJECT_ROOT/project/board/stories"
|
|
30
37
|
TASKS_DIR="$PROJECT_ROOT/project/board/tasks"
|
|
31
38
|
|
package/skills/j-commit/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: j.commit
|
|
3
|
-
description:
|
|
3
|
+
description: Commit implemented epic, story, or task work using the EST naming convention. Also handles user-action prerequisites and new-epic boundaries. Use after completing any EST work item.
|
|
4
4
|
keywords:
|
|
5
5
|
- commit
|
|
6
6
|
- save
|
|
@@ -8,7 +8,6 @@ keywords:
|
|
|
8
8
|
- done
|
|
9
9
|
- push
|
|
10
10
|
- j-commit
|
|
11
|
-
- polyfill
|
|
12
11
|
examples:
|
|
13
12
|
- "commit this work"
|
|
14
13
|
- "save my changes"
|
|
@@ -17,9 +16,9 @@ examples:
|
|
|
17
16
|
|
|
18
17
|
# Commit — Commit Completed Work
|
|
19
18
|
|
|
20
|
-
|
|
19
|
+
`skills/j-commit/` is the **canonical, hand-edited** directory for this skill, per CLAUDE.md's "The Canonical Naming Contract" (the `E50` reopening of 2026-09-09, which promoted `skills/j-commit/` from generated twin to sole canonical form). The `j-` prefix is there for collision safety — a real directory under a distinct name, so a host tool shipping its own same-named built-in command cannot shadow it (Claude Code's native skill resolution is a literal-string, directory-name-based match; see `docs/skill-authoring.md`'s "Invocation Convention").
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
> ⚠️ **`scripts/generate-j-alias.sh` was retired by `E50_S14` and no longer exists — there is nothing to run.** This file was previously generated from a bare `skills/commit/SKILL.md` source; `E50_S15` deleted that directory. This file is now the sole canonical, hand-edited source for this skill — edit it directly.
|
|
23
22
|
|
|
24
23
|
## Inline Mode (called by /do for inline-scoped tasks)
|
|
25
24
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: j.continue
|
|
3
|
-
description:
|
|
3
|
+
description: Check project status across PROJECT_SUMMARY.md, epics, and stories to determine what should be done next. Reports "All done!" if everything is complete.
|
|
4
4
|
keywords:
|
|
5
5
|
- continue
|
|
6
6
|
- next
|
|
@@ -8,7 +8,6 @@ keywords:
|
|
|
8
8
|
- what's next
|
|
9
9
|
- status
|
|
10
10
|
- j-continue
|
|
11
|
-
- polyfill
|
|
12
11
|
examples:
|
|
13
12
|
- "what should I do next?"
|
|
14
13
|
- "continue with the project"
|
|
@@ -17,17 +16,17 @@ examples:
|
|
|
17
16
|
|
|
18
17
|
# Continue — Pick Up the Next Work Item
|
|
19
18
|
|
|
20
|
-
|
|
19
|
+
`skills/j-continue/` is the **canonical, hand-edited** directory for this skill, per CLAUDE.md's "The Canonical Naming Contract" (the `E50` reopening of 2026-09-09, which promoted `skills/j-continue/` from generated twin to sole canonical form). The `j-` prefix is there for collision safety — a real directory under a distinct name, so a host tool shipping its own same-named built-in command cannot shadow it (Claude Code's native skill resolution is a literal-string, directory-name-based match; see `docs/skill-authoring.md`'s "Invocation Convention").
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
> ⚠️ **`scripts/generate-j-alias.sh` was retired by `E50_S14` and no longer exists — there is nothing to run.** This file was previously generated from a bare `skills/continue/SKILL.md` source; `E50_S15` deleted that directory. This file is now the sole canonical, hand-edited source for this skill — edit it directly.
|
|
23
22
|
|
|
24
23
|
## Instructions
|
|
25
24
|
|
|
26
25
|
1. **Check `project/PROJECT_SUMMARY.md`** — Determine if there is outstanding work at the project level.
|
|
27
26
|
|
|
28
|
-
2. **Check `project/epics/`** — If the project summary is done, check if any epics have remaining work.
|
|
27
|
+
2. **Check `project/board/epics/`** — If the project summary is done, check if any epics have remaining work.
|
|
29
28
|
|
|
30
|
-
3. **Check `project/stories/`** — If epics are done, check if any stories have remaining work.
|
|
29
|
+
3. **Check `project/board/stories/`** — If epics are done, check if any stories have remaining work.
|
|
31
30
|
|
|
32
31
|
**Important:** Always check story status within an epic even if the epic itself is marked as done.
|
|
33
32
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: j.deep-dive
|
|
3
|
-
description:
|
|
3
|
+
description: ">."
|
|
4
4
|
metadata:
|
|
5
5
|
prefered_agent: scrum_master
|
|
6
6
|
keywords:
|
|
@@ -9,7 +9,6 @@ keywords:
|
|
|
9
9
|
- "analyze thoroughly"
|
|
10
10
|
- "think through"
|
|
11
11
|
- j-deep-dive
|
|
12
|
-
- polyfill
|
|
13
12
|
examples:
|
|
14
13
|
- "deep dive on this idea"
|
|
15
14
|
- "let's think through this properly"
|
|
@@ -20,9 +19,9 @@ examples:
|
|
|
20
19
|
|
|
21
20
|
# /deep-dive — Deep Investigation Workflow
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
`skills/j-deep-dive/` is the **canonical, hand-edited** directory for this skill, per CLAUDE.md's "The Canonical Naming Contract" (the `E50` reopening of 2026-09-09, which promoted `skills/j-deep-dive/` from generated twin to sole canonical form). The `j-` prefix is there for collision safety — a real directory under a distinct name, so a host tool shipping its own same-named built-in command cannot shadow it (Claude Code's native skill resolution is a literal-string, directory-name-based match; see `docs/skill-authoring.md`'s "Invocation Convention").
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
> ⚠️ **`scripts/generate-j-alias.sh` was retired by `E50_S14` and no longer exists — there is nothing to run.** This file was previously generated from a bare `skills/deep-dive/SKILL.md` source; `E50_S15` deleted that directory. This file is now the sole canonical, hand-edited source for this skill — edit it directly.
|
|
26
25
|
|
|
27
26
|
## Overview
|
|
28
27
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: j.distribute
|
|
3
|
-
description:
|
|
3
|
+
description: Distribute Jenga AI framework files from this private monorepo to one or more consuming projects via the local filesystem. Manages release type selection, version bumping, dry-run preview, per-target file copy, and a post-distribution git commit.
|
|
4
4
|
keywords:
|
|
5
5
|
- distribute
|
|
6
6
|
- private distribution
|
|
@@ -9,7 +9,6 @@ keywords:
|
|
|
9
9
|
- version bump
|
|
10
10
|
- distribute to projects
|
|
11
11
|
- j-distribute
|
|
12
|
-
- polyfill
|
|
13
12
|
examples:
|
|
14
13
|
- "/distribute"
|
|
15
14
|
- "/distribute /path/to/consuming-project"
|
|
@@ -19,9 +18,9 @@ examples:
|
|
|
19
18
|
|
|
20
19
|
# Distribute
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
`skills/j-distribute/` is the **canonical, hand-edited** directory for this skill, per CLAUDE.md's "The Canonical Naming Contract" (the `E50` reopening of 2026-09-09, which promoted `skills/j-distribute/` from generated twin to sole canonical form). The `j-` prefix is there for collision safety — a real directory under a distinct name, so a host tool shipping its own same-named built-in command cannot shadow it (Claude Code's native skill resolution is a literal-string, directory-name-based match; see `docs/skill-authoring.md`'s "Invocation Convention").
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
> ⚠️ **`scripts/generate-j-alias.sh` was retired by `E50_S14` and no longer exists — there is nothing to run.** This file was previously generated from a bare `skills/distribute/SKILL.md` source; `E50_S15` deleted that directory. This file is now the sole canonical, hand-edited source for this skill — edit it directly.
|
|
25
24
|
|
|
26
25
|
Copies Jenga AI framework files from this monorepo to all active consuming projects registered in `distribute.config.json`. Manages the full version lifecycle: release type selection, `package.json` version bump, dry-run preview, per-target file copy, and a final git commit of the version bump.
|
|
27
26
|
|
package/skills/j-do/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: j.do
|
|
3
|
-
description:
|
|
3
|
+
description: Execute tasks from the scrum board. Reads from project/todo.md, resolves each entry to its full scrum board context, and drives the developer agent through implementation with the correct sender object and communication contract. Loops until all selected tasks are done or the user exits.
|
|
4
4
|
keywords:
|
|
5
5
|
- do
|
|
6
6
|
- execute
|
|
@@ -8,7 +8,6 @@ keywords:
|
|
|
8
8
|
- work on
|
|
9
9
|
- build
|
|
10
10
|
- j-do
|
|
11
|
-
- polyfill
|
|
12
11
|
examples:
|
|
13
12
|
- "implement the login feature"
|
|
14
13
|
- "work on the API endpoint"
|
|
@@ -26,11 +25,10 @@ directory under a distinct name, so a host tool shipping its own same-named buil
|
|
|
26
25
|
shadow it (Claude Code's native skill resolution is a literal-string, directory-name-based match; see
|
|
27
26
|
`docs/skill-authoring.md`'s "Invocation Convention").
|
|
28
27
|
|
|
29
|
-
> ⚠️
|
|
30
|
-
> previously generated from `skills/do/SKILL.md
|
|
31
|
-
>
|
|
32
|
-
>
|
|
33
|
-
> CLAUDE.md states the same prohibition in general terms; this is the concrete instance of it.
|
|
28
|
+
> ⚠️ **`scripts/generate-j-alias.sh` was retired by `E50_S14` and no longer exists — there is
|
|
29
|
+
> nothing to run.** This file was previously generated from a bare `skills/do/SKILL.md` source;
|
|
30
|
+
> `E50_S15` deleted that directory. This file is now the sole canonical, hand-edited source for
|
|
31
|
+
> this skill — edit it directly.
|
|
34
32
|
|
|
35
33
|
## `--trivial` Flag
|
|
36
34
|
|
|
@@ -194,7 +192,7 @@ After acquiring the epic lock and before writing the bundle manifest, scan all o
|
|
|
194
192
|
|
|
195
193
|
1. **Extract expected files** from the task's frontmatter field `scope_rationale` and from the task's `## Description` section. Use a best-effort prose heuristic: split the text on whitespace and punctuation, then retain any token that either (a) contains a `/` character or (b) matches the pattern `*.*` (a dot surrounded by non-dot characters on both sides, e.g. `SKILL.md`, `foo.json`). Collect all retained tokens into a set called `expected_files`. This is intentionally permissive — false positives (expected files that were never actually changed) are acceptable and produce no report.
|
|
196
194
|
|
|
197
|
-
2. **Compute unexpected files**: let `actual_files` = the array stored at `task_changed_files[<task_id>]` in the bundle manifest (from step c.1). Compute `unexpected = actual_files − expected_files` (set difference: files in `actual_files` that have no match in `expected_files`). Matching is case-sensitive and exact against the relative path or the basename of the path — a token like `SKILL.md` matches any actual file whose basename is `SKILL.md` (e.g. `skills/do/SKILL.md`).
|
|
195
|
+
2. **Compute unexpected files**: let `actual_files` = the array stored at `task_changed_files[<task_id>]` in the bundle manifest (from step c.1). Compute `unexpected = actual_files − expected_files` (set difference: files in `actual_files` that have no match in `expected_files`). Matching is case-sensitive and exact against the relative path or the basename of the path — a token like `SKILL.md` matches any actual file whose basename is `SKILL.md` (e.g. `skills/j-do/SKILL.md`).
|
|
198
196
|
|
|
199
197
|
3. **If `unexpected` is non-empty**:
|
|
200
198
|
a. Write a Markdown conflict report to `project/queue/conflict-<task_id>.md` with the following structure:
|
|
@@ -235,14 +233,14 @@ After acquiring the epic lock and before writing the bundle manifest, scan all o
|
|
|
235
233
|
2. Create the lock file: write the current ISO 8601 timestamp into `project/board/tasks/<task_id>_*.md.lock`.
|
|
236
234
|
3. Update the task frontmatter field `status: Failed`.
|
|
237
235
|
4. Delete the lock file immediately after the write completes.
|
|
238
|
-
Then invoke the rollback anchor cleanup procedure (see "### Bundle Manifest and Rollback Anchor" — failure path). After the rollback anchor completes, **release the developer concurrency slot** acquired in step 3 above: `scripts/release-concurrency-slot.sh developer <E##_S##> <orchestrator_session_id>` (per `### 4.4` step 2 below). Then **release the epic lock**: run `rm -f project/queue/epic-lock-<E##>.json`. Mark the bundle as failed and **halt** — do not execute any remaining tasks in the sequence.
|
|
236
|
+
Then invoke the rollback anchor cleanup procedure (see "### Bundle Manifest and Rollback Anchor" — failure path). After the rollback anchor completes, **release the developer concurrency slot** acquired in step 3 above: `"$([ -f scripts/release-concurrency-slot.sh ] && echo scripts/release-concurrency-slot.sh || echo node_modules/@jenga-ai/agent/scripts/release-concurrency-slot.sh)" developer <E##_S##> <orchestrator_session_id>` (per `### 4.4` step 2 below). Then **release the epic lock**: run `rm -f project/queue/epic-lock-<E##>.json`. Mark the bundle as failed and **halt** — do not execute any remaining tasks in the sequence.
|
|
239
237
|
|
|
240
238
|
5. **Post-bundle verification** (runs only if all tasks completed without failure):
|
|
241
239
|
- Inspect each task in the bundle for `needs_docs: true` in its frontmatter.
|
|
242
240
|
- **If any task has `needs_docs: true`**: invoke the tester agent once for the full story. Pass the story ID, the list of all task IDs in the bundle, and the shared worktree path. The tester is responsible for updating individual task statuses.
|
|
243
241
|
- **If all tasks have `needs_docs: false`**: the developer agent self-verifies — reviews each task's implementation against its acceptance criteria without invoking the tester. After self-verification passes, write `status: Passed` and `date_completed: <YYYY-MM-DD>` (today's date) to each task file using the file-locking protocol (steps c.1–c.4 above). No tester invocation occurs.
|
|
244
242
|
|
|
245
|
-
6. **Cleanup**: on successful bundle completion, invoke the rollback anchor success path (see "### Bundle Manifest and Rollback Anchor" — success path) to delete the bundle manifest. Then **release the developer concurrency slot** acquired in step 3 above: `scripts/release-concurrency-slot.sh developer <E##_S##> <orchestrator_session_id>` (per `### 4.4` step 2 below). Then **release the epic lock**: run `rm -f project/queue/epic-lock-<E##>.json`.
|
|
243
|
+
6. **Cleanup**: on successful bundle completion, invoke the rollback anchor success path (see "### Bundle Manifest and Rollback Anchor" — success path) to delete the bundle manifest. Then **release the developer concurrency slot** acquired in step 3 above: `"$([ -f scripts/release-concurrency-slot.sh ] && echo scripts/release-concurrency-slot.sh || echo node_modules/@jenga-ai/agent/scripts/release-concurrency-slot.sh)" developer <E##_S##> <orchestrator_session_id>` (per `### 4.4` step 2 below). Then **release the epic lock**: run `rm -f project/queue/epic-lock-<E##>.json`.
|
|
246
244
|
|
|
247
245
|
### Bundle Manifest and Rollback Anchor
|
|
248
246
|
|
|
@@ -443,7 +441,7 @@ After resolving the task context (step 4), passing override validation (step 4.1
|
|
|
443
441
|
|
|
444
442
|
1. **Acquire a developer concurrency slot, then spawn a developer subagent.** Acquire first, per `### 4.4. Developer Concurrency Slot Enforcement` below (`<id>` = this task's id). On a full cap (`capacity_blocked` outcome), do not spawn anything — `### 4.4` already reverts this task's status to `Pending`, logs the `capacity_blocked` event, and tracks the consecutive-block count; stop here and let `/jenga` Phase 4 retry this task on a later wave once a slot frees up. On a successful acquire, spawn the subagent (Agent tool, `subagent_type: "developer"`) with the same sender object and context payload as step 5 would use, but with an explicit instruction added to the dispatch prompt: **do not create a worktree** — implement directly against the current checkout (the session's existing working tree), not an isolated `.claude/worktrees/<slug>` copy. This is the one concrete difference from the step-5 `task` path: everything else about how the subagent implements the task (reading the task file, following acceptance criteria, following repo conventions) is unchanged.
|
|
445
443
|
|
|
446
|
-
2. **After the developer subagent reports implementation complete**, first **release the developer concurrency slot** acquired in step 1: `scripts/release-concurrency-slot.sh developer <task_id> <orchestrator_session_id>` (per `### 4.4` step 2) — this subagent's session has ended, so the slot is released now regardless of what it reports, before the smoke test result is even known. Then run the smoke test harness using the same invocation convention as `### 4.2. Inline Execution Path`:
|
|
444
|
+
2. **After the developer subagent reports implementation complete**, first **release the developer concurrency slot** acquired in step 1: `"$([ -f scripts/release-concurrency-slot.sh ] && echo scripts/release-concurrency-slot.sh || echo node_modules/@jenga-ai/agent/scripts/release-concurrency-slot.sh)" developer <task_id> <orchestrator_session_id>` (per `### 4.4` step 2) — this subagent's session has ended, so the slot is released now regardless of what it reports, before the smoke test result is even known. Then run the smoke test harness using the same invocation convention as `### 4.2. Inline Execution Path`:
|
|
447
445
|
- Run `bash "$([ -f scripts/smoke-harness.sh ] && echo scripts/smoke-harness.sh || echo node_modules/@jenga-ai/agent/scripts/smoke-harness.sh)" <changed_file>...`, passing the paths the subagent changed. With no arguments the harness infers them from `git diff --name-only HEAD`. It exits `0` on pass and `1` on failure.
|
|
448
446
|
- If neither `scripts/smoke-harness.sh` nor `node_modules/@jenga-ai/agent/scripts/smoke-harness.sh` exists, log a warning and treat the result as a pass:
|
|
449
447
|
```
|
|
@@ -468,7 +466,7 @@ This is a self-contained, reusable procedure with two current callers — `### 4
|
|
|
468
466
|
2. **Create a worktree** for the task, named `<E##_S##_T##-short-slug>` per standard Worktree Management conventions, if one does not already exist for this task. (A task dispatched under `light` scope, or forced `inline` via `--trivial`, never had one — both premises skip worktree creation — so this step always creates a fresh worktree in that case.)
|
|
469
467
|
3. **Acquire a developer concurrency slot** (per `### 4.4. Developer Concurrency Slot Enforcement` below, `<id>` = this task's id). This fallback spawn is a distinct developer-subagent lifecycle from whatever `light`/`trivial` attempt preceded it — that attempt's own slot, if any, was already acquired and released around it (`### 4.3` step 1/2, or no slot at all for a `--trivial`-forced inline attempt, which never spawns a subagent) — so this step always acquires its own fresh slot. On a full cap (`capacity_blocked` outcome), do not spawn anything here either: apply `### 4.4`'s Pending-revert/log/consecutive-block handling for this task id and stop the fallback. The task remains exactly as the reduced-overhead attempt left it (any commits already made by that attempt stay in the worktree/branch just created in step 2), and `/jenga` Phase 4 retries it on a later wave once a slot frees up.
|
|
470
468
|
4. **Spawn a developer subagent** in that worktree and have it pick up from the current state of the code (the changes already made by the reduced-overhead attempt are still present in the working tree / already committed, if any commit occurred — the subagent continues from there rather than starting over).
|
|
471
|
-
5. **Invoke the tester agent** per the normal `### 5. Invoke the developer agent` flow's contract — full sender object, commit SHAs, worktree path. The tester is responsible for the terminal status write, exactly as in the standard `task`-scope pipeline. Once this developer subagent's session ends — tester-verified, failed, or errored — **release the slot** acquired in step 3: `scripts/release-concurrency-slot.sh developer <task_id> <orchestrator_session_id>` (per `### 4.4` step 2).
|
|
469
|
+
5. **Invoke the tester agent** per the normal `### 5. Invoke the developer agent` flow's contract — full sender object, commit SHAs, worktree path. The tester is responsible for the terminal status write, exactly as in the standard `task`-scope pipeline. Once this developer subagent's session ends — tester-verified, failed, or errored — **release the slot** acquired in step 3: `"$([ -f scripts/release-concurrency-slot.sh ] && echo scripts/release-concurrency-slot.sh || echo node_modules/@jenga-ai/agent/scripts/release-concurrency-slot.sh)" developer <task_id> <orchestrator_session_id>` (per `### 4.4` step 2).
|
|
472
470
|
6. **Emit a clear, non-fatal fallback notice** to the user/orchestrator, using the message matching the caller's origin:
|
|
473
471
|
- origin `light`:
|
|
474
472
|
```
|
|
@@ -497,7 +495,7 @@ Detecting which case applies is mechanical: if the dispatch context already cont
|
|
|
497
495
|
|
|
498
496
|
1. **Acquire.** Before spawning the developer subagent (or the bundle's shared developer subagent), run:
|
|
499
497
|
```
|
|
500
|
-
scripts/acquire-concurrency-slot.sh developer <id> <orchestrator_session_id>
|
|
498
|
+
"$([ -f scripts/acquire-concurrency-slot.sh ] && echo scripts/acquire-concurrency-slot.sh || echo node_modules/@jenga-ai/agent/scripts/acquire-concurrency-slot.sh)" developer <id> <orchestrator_session_id>
|
|
501
499
|
```
|
|
502
500
|
Per that script's own exit-code contract:
|
|
503
501
|
- **Exit `0`** — slot acquired. Proceed to spawn the subagent exactly as documented at the calling site, and carry out step 2 below (release) once that subagent's session ends.
|
|
@@ -523,7 +521,7 @@ Detecting which case applies is mechanical: if the dispatch context already cont
|
|
|
523
521
|
|
|
524
522
|
2. **Release — on every subagent exit path.** Once the spawned developer subagent's session ends — whether it reports success, failure, or an error/exception — run:
|
|
525
523
|
```
|
|
526
|
-
scripts/release-concurrency-slot.sh developer <id> <orchestrator_session_id>
|
|
524
|
+
"$([ -f scripts/release-concurrency-slot.sh ] && echo scripts/release-concurrency-slot.sh || echo node_modules/@jenga-ai/agent/scripts/release-concurrency-slot.sh)" developer <id> <orchestrator_session_id>
|
|
527
525
|
```
|
|
528
526
|
This call is unconditional and must be reached from every branch that follows a successful acquire in step 1: the success path, the ordinary `/do` failure→skip→`Pending` path, and any other error/exception branch that aborts the calling section early. `release-concurrency-slot.sh` is idempotent by its own contract (a no-op success if the holder entry is already absent), so calling it defensively — even in a code path where it is uncertain whether the acquire actually landed — is always safe and never an error.
|
|
529
527
|
|
|
@@ -564,7 +562,7 @@ The developer agent will:
|
|
|
564
562
|
- Implement, commit at milestones, and invoke the tester agent
|
|
565
563
|
- Return when the tester has verified the work
|
|
566
564
|
|
|
567
|
-
**Release the slot on every exit path.** Once the developer agent's session ends — whether it returns having implemented and been verified by the tester, fails outright, or errors — release the slot immediately: `scripts/release-concurrency-slot.sh developer <task_id> <orchestrator_session_id>` (per `### 4.4` step 2). This applies uniformly to the success path above, `/jenga`'s existing "`/do` failure (background agent)" skip-to-`Pending` path (`skills/jenga/SKILL.md`'s Edge Cases), and any other error/exception that aborts this section early.
|
|
565
|
+
**Release the slot on every exit path.** Once the developer agent's session ends — whether it returns having implemented and been verified by the tester, fails outright, or errors — release the slot immediately: `"$([ -f scripts/release-concurrency-slot.sh ] && echo scripts/release-concurrency-slot.sh || echo node_modules/@jenga-ai/agent/scripts/release-concurrency-slot.sh)" developer <task_id> <orchestrator_session_id>` (per `### 4.4` step 2). This applies uniformly to the success path above, `/jenga`'s existing "`/do` failure (background agent)" skip-to-`Pending` path (`skills/jenga/SKILL.md`'s Edge Cases), and any other error/exception that aborts this section early.
|
|
568
566
|
|
|
569
567
|
### 5.1. Intent-vs-Diff Check (needs_docs: false only)
|
|
570
568
|
|
package/skills/j-doc/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: j.doc
|
|
3
|
-
description:
|
|
3
|
+
description: Generate or update a documentation file by resolving a target path to a clear documentation objective before writing.
|
|
4
4
|
metadata:
|
|
5
5
|
prefered_agent: developer
|
|
6
6
|
keywords:
|
|
@@ -10,7 +10,6 @@ keywords:
|
|
|
10
10
|
- generate docs
|
|
11
11
|
- update docs
|
|
12
12
|
- j-doc
|
|
13
|
-
- polyfill
|
|
14
13
|
examples:
|
|
15
14
|
- "/doc"
|
|
16
15
|
- "/doc docs/API.md"
|
|
@@ -22,9 +21,9 @@ examples:
|
|
|
22
21
|
|
|
23
22
|
# Doc — Documentation Synthesis and Regeneration
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
`skills/j-doc/` is the **canonical, hand-edited** directory for this skill, per CLAUDE.md's "The Canonical Naming Contract" (the `E50` reopening of 2026-09-09, which promoted `skills/j-doc/` from generated twin to sole canonical form). The `j-` prefix is there for collision safety — a real directory under a distinct name, so a host tool shipping its own same-named built-in command cannot shadow it (Claude Code's native skill resolution is a literal-string, directory-name-based match; see `docs/skill-authoring.md`'s "Invocation Convention").
|
|
26
25
|
|
|
27
|
-
|
|
26
|
+
> ⚠️ **`scripts/generate-j-alias.sh` was retired by `E50_S14` and no longer exists — there is nothing to run.** This file was previously generated from a bare `skills/doc/SKILL.md` source; `E50_S15` deleted that directory. This file is now the sole canonical, hand-edited source for this skill — edit it directly.
|
|
28
27
|
|
|
29
28
|
## Input Format
|
|
30
29
|
|