@jenga-ai/agent 3.5.0 → 3.6.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 +85 -78
- package/agents/developer.md +1 -1
- package/agents/scrum-master.md +20 -2
- package/agents/tester.md +3 -3
- package/hooks/on_session_end.sh +5 -5
- package/lib/generate-agent-context.js +2 -2
- package/lib/generate-copilot-hooks.js +1 -1
- package/lib/generate-skill-allow-list.js +37 -3
- package/lib/mirror.js +1 -1
- package/lib/postinstall-manifest.js +1 -1
- package/lib/skill-allow-list.json +2 -2
- package/mcp/help/index.js +8 -17
- package/mcp/help/scan.js +73 -0
- package/package.json +6 -1
- package/project/app/api/parsers/knowledge-graph.js +100 -9
- package/project/app/api/routes/health.js +36 -0
- package/project/app/api/scripts/capture-snapshot.js +9 -6
- package/project/app/ui/dist/assets/{index-CdK3Qrep.css → index-BVR_7Owg.css} +1 -1
- package/project/app/ui/dist/assets/index-CtU2xLQm.js +104 -0
- package/project/app/ui/dist/index.html +2 -2
- package/project/app/ui/package.json +4 -0
- package/project/app/ui/scripts/build-snapshot-html.cjs +63 -2
- package/scripts/acquire-concurrency-slot.sh +1 -1
- package/scripts/apply-j-prefix.sh +46 -5
- package/scripts/audit-twin-divergence.sh +73 -5
- package/scripts/build-pages-site.sh +1 -1
- package/scripts/check-public-playbook-steps.sh +158 -52
- package/scripts/check-publicignore-match.sh +2 -2
- package/scripts/compute-deploy-reconcile.sh +5 -5
- package/scripts/delete-bare-skill-dirs.sh +330 -0
- package/scripts/generate-legacy-shipped-paths.js +2 -2
- package/scripts/idea_manager.sh +258 -3
- package/scripts/mark-deployed.sh +2 -2
- package/scripts/populate-knowledge-graph.entity-resolution.test.js +254 -0
- package/scripts/populate-knowledge-graph.js +213 -5
- package/scripts/populate-knowledge-graph.staleness.test.js +130 -0
- package/scripts/postinstall.js +1 -1
- package/scripts/repoint-skill-refs.sh +539 -0
- package/scripts/todo_manager.sh +1 -1
- package/scripts/verify-legacy-seed-reconcile.sh +10 -10
- package/scripts/verify-postinstall-reconcile.sh +7 -7
- package/scripts/write-context-digest.sh +1 -1
- package/skills/j-clearify/SKILL.md +2 -2
- package/skills/j-close-story/scripts/check-privatized.sh +4 -4
- package/skills/j-distribute/CONFIG_SCHEMA.md +82 -5
- package/skills/j-do/SKILL.md +101 -17
- package/skills/j-doc-sync/SKILL.md +1 -0
- package/skills/j-gitignore/SKILL.md +157 -0
- package/skills/j-gitignore/assets/jenga-paths.txt +50 -0
- package/skills/j-gitignore/scripts/_catalog.sh +105 -0
- package/skills/j-gitignore/scripts/audit-gitignore.sh +194 -0
- package/skills/j-gitignore/scripts/repair-gitignore.sh +226 -0
- package/skills/j-gitignore/scripts/untrack-jenga-files.sh +210 -0
- package/skills/j-idea/SKILL.md +78 -6
- package/skills/j-idea/assets/idea_template.md +1 -1
- package/skills/j-improve/SKILL.md +1 -1
- package/skills/j-init/SKILL.md +3 -3
- package/skills/j-init/assets/scope-thresholds_template.json +5 -2
- package/skills/j-init/scripts/apply-scaffold-visibility.sh +1 -1
- package/skills/j-init/scripts/init.sh +4 -4
- package/skills/j-playbook/SKILL.md +1 -1
- package/skills/j-publish/SKILL.md +1 -1
- package/skills/j-publish/adapters/npm-ci.md +6 -1
- package/skills/j-publish/adapters/npm.md +1 -1
- package/skills/j-publish/scripts/generate_release_notes.sh +1 -1
- package/skills/j-publish/scripts/npm_stage_inspect.sh +61 -0
- package/skills/j-reconcile/SKILL.md +2 -2
- package/skills/j-reconcile/scripts/detect-unlinked-code.sh +11 -11
- package/skills/j-redo/SKILL.md +1 -1
- package/skills/j-spinoff/SKILL.md +1 -1
- package/skills/j-status/SKILL.md +15 -0
- package/skills/j-todo/SKILL.md +3 -1
- package/skills/j-uncharted/SKILL.md +1 -1
- package/skills/j-uncharted/scripts/detect-dependencies.sh +1 -1
- package/skills/j-uncharted/scripts/detect-tests.sh +1 -1
- package/skills/j-uncharted/scripts/elicitation-state.sh +1 -1
- package/skills/j-uncharted/scripts/validate-proposed-items.sh +1 -1
- package/skills/j-wtf/SKILL.md +1 -1
- package/skills/jenga/SKILL.md +43 -9
- package/skills/jenga/playbooks/board-hygiene.json +32 -0
- package/skills/jenga/playbooks/schema.json +73 -6
- package/skills/jenga/playbooks/understand-then-commit.json +19 -0
- package/skills/jenga/scripts/load-nl-catalog.sh +1 -1
- package/skills/jenga/scripts/load-playbooks.sh +1 -1
- package/skills/jenga/scripts/match-playbook.sh +1 -1
- package/templates/SCRUM_BOARD_SCHEMA.md +14 -1
- package/templates/SKILL_TEMPLATE.md +12 -0
- 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 +34 -6
- package/project/app/ui/dist/assets/index-7fj-vllY.js +0 -104
- package/scripts/generate-j-alias.sh +0 -333
- package/skills/j-dev-done/SKILL.md +0 -53
- package/skills/j-dev-done/scripts/classify-commit-outcome.sh +0 -114
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# -----------------------------------------------------------------------------
|
|
3
|
+
# skills/j-gitignore/scripts/untrack-jenga-files.sh
|
|
4
|
+
#
|
|
5
|
+
# Removes Jenga-owned paths from git WITHOUT removing them from disk —
|
|
6
|
+
# `git rm -r --cached`, never a plain `git rm`. The files stay exactly where
|
|
7
|
+
# they are; git simply stops tracking them, and the .gitignore entries written
|
|
8
|
+
# by repair-gitignore.sh then keep them from coming back.
|
|
9
|
+
#
|
|
10
|
+
# Run repair-gitignore.sh FIRST. .gitignore has no effect on an already-tracked
|
|
11
|
+
# file, so untracking without the entries in place just means the next
|
|
12
|
+
# `git add -A` re-adds everything.
|
|
13
|
+
#
|
|
14
|
+
# ─── What "removed from origin" does and does not mean ──────────────────────
|
|
15
|
+
# With --commit --push, these paths disappear from the branch TIP on the
|
|
16
|
+
# remote: clone it fresh and they are gone. Earlier commits are UNTOUCHED —
|
|
17
|
+
# the blobs remain reachable in history, so this is not a secret-scrubbing
|
|
18
|
+
# tool. If something sensitive was committed, treat it as compromised, rotate
|
|
19
|
+
# it, and use a history-rewriting tool (git-filter-repo) separately.
|
|
20
|
+
#
|
|
21
|
+
# Invoked via `bash`, not executed directly.
|
|
22
|
+
#
|
|
23
|
+
# Usage:
|
|
24
|
+
# untrack-jenga-files.sh [project_root]
|
|
25
|
+
# [--tiers scaffold,hybrid,board,optional]
|
|
26
|
+
# [--dry-run] [--commit] [--push]
|
|
27
|
+
# [--allow-dirty-index]
|
|
28
|
+
#
|
|
29
|
+
# Options:
|
|
30
|
+
# --dry-run List what would be untracked; touch nothing.
|
|
31
|
+
# --commit Commit the removals. Without it, changes are left
|
|
32
|
+
# staged for you to inspect and commit yourself.
|
|
33
|
+
# --push Push to the branch's upstream. Requires --commit.
|
|
34
|
+
# Never implied — this is the only outward-facing step.
|
|
35
|
+
# --allow-dirty-index Proceed even if unrelated changes are already staged.
|
|
36
|
+
# Off by default so this can never sweep your staged
|
|
37
|
+
# work into its commit.
|
|
38
|
+
#
|
|
39
|
+
# Exit codes:
|
|
40
|
+
# 0 Success (including "nothing tracked — nothing to do")
|
|
41
|
+
# 1 Bad usage or missing prerequisite
|
|
42
|
+
# 2 Invalid tier
|
|
43
|
+
# 3 git operation failed
|
|
44
|
+
# 4 Refused: index already dirty, or --push without --commit
|
|
45
|
+
# -----------------------------------------------------------------------------
|
|
46
|
+
|
|
47
|
+
set -uo pipefail
|
|
48
|
+
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/_catalog.sh"
|
|
49
|
+
|
|
50
|
+
info() { echo "[untrack] $*"; }
|
|
51
|
+
warn() { echo "[untrack] WARNING: $*"; }
|
|
52
|
+
err() { echo "[untrack] ERROR: $*" >&2; }
|
|
53
|
+
|
|
54
|
+
PROJECT_ROOT=""
|
|
55
|
+
TIERS="scaffold"
|
|
56
|
+
DRY_RUN=0
|
|
57
|
+
DO_COMMIT=0
|
|
58
|
+
DO_PUSH=0
|
|
59
|
+
ALLOW_DIRTY=0
|
|
60
|
+
|
|
61
|
+
while [ $# -gt 0 ]; do
|
|
62
|
+
case "$1" in
|
|
63
|
+
--tiers) TIERS="${2:-}"; shift 2 ;;
|
|
64
|
+
--tiers=*) TIERS="${1#*=}"; shift ;;
|
|
65
|
+
--dry-run) DRY_RUN=1; shift ;;
|
|
66
|
+
--commit) DO_COMMIT=1; shift ;;
|
|
67
|
+
--push) DO_PUSH=1; shift ;;
|
|
68
|
+
--allow-dirty-index) ALLOW_DIRTY=1; shift ;;
|
|
69
|
+
-h|--help)
|
|
70
|
+
echo "Usage: $(basename "$0") [project_root] [--tiers <csv>] [--dry-run] [--commit] [--push] [--allow-dirty-index]"
|
|
71
|
+
exit 0 ;;
|
|
72
|
+
-*) err "Unknown option: $1"; exit 1 ;;
|
|
73
|
+
*)
|
|
74
|
+
if [ -n "$PROJECT_ROOT" ]; then err "More than one project root given."; exit 1; fi
|
|
75
|
+
PROJECT_ROOT="$1"; shift ;;
|
|
76
|
+
esac
|
|
77
|
+
done
|
|
78
|
+
|
|
79
|
+
if [ "$DO_PUSH" -eq 1 ] && [ "$DO_COMMIT" -eq 0 ]; then
|
|
80
|
+
err "--push requires --commit. There would be nothing to push."
|
|
81
|
+
exit 4
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
PROJECT_ROOT="${PROJECT_ROOT:-$PWD}"
|
|
85
|
+
validate_tiers "$TIERS" || exit 2
|
|
86
|
+
resolve_root "$PROJECT_ROOT" || exit 1
|
|
87
|
+
load_catalog "$TIERS" || exit 1
|
|
88
|
+
|
|
89
|
+
# ─── Refuse to run on a dirty index ─────────────────────────────────────────
|
|
90
|
+
# .gitignore is the one staged path that is never "unrelated": it is the
|
|
91
|
+
# companion change repair-gitignore.sh just made, and untracking without it is
|
|
92
|
+
# pointless. Staged alone, it is allowed through and folded into this commit.
|
|
93
|
+
# Anything else staged is refused.
|
|
94
|
+
if [ "$ALLOW_DIRTY" -eq 0 ] && [ "$DRY_RUN" -eq 0 ]; then
|
|
95
|
+
if ! git diff --cached --quiet 2>/dev/null; then
|
|
96
|
+
staged="$(git diff --cached --name-only)"
|
|
97
|
+
if [ "$staged" = ".gitignore" ]; then
|
|
98
|
+
info "Staged .gitignore detected — folding the ignore-rule change into this commit."
|
|
99
|
+
else
|
|
100
|
+
err "The index already has staged changes:"
|
|
101
|
+
printf '%s\n' "$staged" | sed 's/^/ /' >&2
|
|
102
|
+
err "Refusing to run — a --commit here would sweep them into this commit."
|
|
103
|
+
err "Commit or unstage them first, or pass --allow-dirty-index if you"
|
|
104
|
+
err "genuinely want them included."
|
|
105
|
+
exit 4
|
|
106
|
+
fi
|
|
107
|
+
fi
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
# ─── Find what is actually tracked ──────────────────────────────────────────
|
|
111
|
+
TRACKED_PATHS=()
|
|
112
|
+
TOTAL_FILES=0
|
|
113
|
+
for i in "${!CATALOG_PATHS[@]}"; do
|
|
114
|
+
path="${CATALOG_PATHS[$i]}"
|
|
115
|
+
count="$(git ls-files -- "$path" 2>/dev/null | wc -l | tr -d ' ')"
|
|
116
|
+
if [ "${count:-0}" -gt 0 ]; then
|
|
117
|
+
TRACKED_PATHS+=("$path")
|
|
118
|
+
TOTAL_FILES=$((TOTAL_FILES + count))
|
|
119
|
+
printf ' %-36s %s tracked file(s)\n' "$path" "$count"
|
|
120
|
+
fi
|
|
121
|
+
done
|
|
122
|
+
|
|
123
|
+
if [ "${#TRACKED_PATHS[@]}" -eq 0 ]; then
|
|
124
|
+
info "No catalog path (tiers: ${TIERS}) is tracked — nothing to untrack."
|
|
125
|
+
exit 0
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
echo
|
|
129
|
+
info "${#TRACKED_PATHS[@]} path(s), ${TOTAL_FILES} file(s) would stop being tracked."
|
|
130
|
+
info "All of them remain on disk — this uses 'git rm -r --cached'."
|
|
131
|
+
|
|
132
|
+
if [ "$DRY_RUN" -eq 1 ]; then
|
|
133
|
+
info "--dry-run — nothing changed."
|
|
134
|
+
exit 0
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
# ─── Untrack ────────────────────────────────────────────────────────────────
|
|
138
|
+
for path in "${TRACKED_PATHS[@]}"; do
|
|
139
|
+
if ! git rm -r --cached --quiet -- "$path"; then
|
|
140
|
+
err "git rm --cached failed for '${path}'. The index may be partially staged;"
|
|
141
|
+
err "inspect with 'git status' and 'git reset' to back out."
|
|
142
|
+
exit 3
|
|
143
|
+
fi
|
|
144
|
+
info "Untracked: ${path}"
|
|
145
|
+
done
|
|
146
|
+
|
|
147
|
+
# Verify nothing was deleted from disk before reporting success.
|
|
148
|
+
MISSING=0
|
|
149
|
+
for path in "${TRACKED_PATHS[@]}"; do
|
|
150
|
+
probe="${path%/}"
|
|
151
|
+
if [ ! -e "$probe" ]; then
|
|
152
|
+
warn "'${probe}' is not on disk. It was already absent before this ran"
|
|
153
|
+
warn "(git tracked it, the working tree did not), so nothing was lost here."
|
|
154
|
+
MISSING=$((MISSING + 1))
|
|
155
|
+
fi
|
|
156
|
+
done
|
|
157
|
+
[ "$MISSING" -eq 0 ] && info "Verified: every untracked path is still present on disk."
|
|
158
|
+
|
|
159
|
+
if [ "$DO_COMMIT" -eq 0 ]; then
|
|
160
|
+
echo
|
|
161
|
+
info "Changes are STAGED but not committed. Review with:"
|
|
162
|
+
info " git status"
|
|
163
|
+
info " git diff --cached --stat"
|
|
164
|
+
info "Then commit yourself, or re-run with --commit."
|
|
165
|
+
exit 0
|
|
166
|
+
fi
|
|
167
|
+
|
|
168
|
+
# ─── Commit ─────────────────────────────────────────────────────────────────
|
|
169
|
+
COMMIT_MSG="chore(jenga): untrack Jenga-owned files, keep them on disk
|
|
170
|
+
|
|
171
|
+
Removes the Jenga scaffold from version control via 'git rm --cached' and
|
|
172
|
+
relies on the j.gitignore managed block to keep it out. Files are untouched
|
|
173
|
+
on disk. Tiers: ${TIERS}.
|
|
174
|
+
|
|
175
|
+
Note: this changes the branch tip only — earlier commits still contain these
|
|
176
|
+
paths."
|
|
177
|
+
|
|
178
|
+
if ! git commit -q -m "$COMMIT_MSG"; then
|
|
179
|
+
err "git commit failed. Your removals are still staged."
|
|
180
|
+
exit 3
|
|
181
|
+
fi
|
|
182
|
+
info "Committed: $(git rev-parse --short HEAD)"
|
|
183
|
+
|
|
184
|
+
if [ "$DO_PUSH" -eq 0 ]; then
|
|
185
|
+
echo
|
|
186
|
+
info "Not pushed. The remote still has these files until you push."
|
|
187
|
+
exit 0
|
|
188
|
+
fi
|
|
189
|
+
|
|
190
|
+
# ─── Push ───────────────────────────────────────────────────────────────────
|
|
191
|
+
BRANCH="$(git rev-parse --abbrev-ref HEAD)"
|
|
192
|
+
UPSTREAM="$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null)"
|
|
193
|
+
|
|
194
|
+
if [ -z "$UPSTREAM" ]; then
|
|
195
|
+
err "Branch '${BRANCH}' has no upstream — refusing to guess a remote."
|
|
196
|
+
err "Set one, then push yourself: git push -u origin ${BRANCH}"
|
|
197
|
+
err "The commit itself succeeded and is safe on your local branch."
|
|
198
|
+
exit 3
|
|
199
|
+
fi
|
|
200
|
+
|
|
201
|
+
info "Pushing ${BRANCH} → ${UPSTREAM} ..."
|
|
202
|
+
if ! git push; then
|
|
203
|
+
err "Push failed — most likely the branch is behind its upstream."
|
|
204
|
+
err "Reconcile (git pull --rebase) and push yourself. The commit is safe locally."
|
|
205
|
+
exit 3
|
|
206
|
+
fi
|
|
207
|
+
|
|
208
|
+
info "Pushed. These paths are gone from ${UPSTREAM}'s tip."
|
|
209
|
+
info "They REMAIN in earlier commits — this did not rewrite history."
|
|
210
|
+
exit 0
|
package/skills/j-idea/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: j.idea
|
|
3
|
-
description: Polyfill alias of the idea skill under a collision-safe directory name. Identical behavior to /idea — Capture a loosely-defined idea to project/ideas.md — a lightweight, "maybe someday" log with no board or promotion overhead. Use when the bare /idea form is shadowed by another tool's own built-in command of the same name.
|
|
3
|
+
description: Polyfill alias of the idea skill under a collision-safe directory name. Identical behavior to /idea — DEPRECATED - use the prefixed 'j-idea' skill instead. Capture a loosely-defined idea to project/ideas.md — a lightweight, "maybe someday" log with no board or promotion overhead. Use when the bare /idea form is shadowed by another tool's own built-in command of the same name.
|
|
4
4
|
keywords:
|
|
5
5
|
- idea
|
|
6
6
|
- capture idea
|
|
@@ -52,12 +52,84 @@ This file is generated/synced by `scripts/generate-j-alias.sh idea` from `skills
|
|
|
52
52
|
- **Promoting an idea** means re-running `/brainstorm` on it, which routes onward to `/btw` or `/todo` as normal. That routing behavior already exists and is out of scope for `/idea`.
|
|
53
53
|
- **Terminal idea states** are marked directly in `project/ideas.md` using the same HTML-comment tag convention `project/todo.md` uses for `RECONCILED`:
|
|
54
54
|
- `PROMOTED` — the idea was picked up via `/brainstorm` and turned into board work.
|
|
55
|
-
- `
|
|
55
|
+
- `REJECTED` — the idea was reviewed and dropped.
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
### Embedded Board ID
|
|
58
|
+
|
|
59
|
+
`PROMOTED`/`REJECTED` tags support an embedded board ID, so the idea→board-item link is
|
|
60
|
+
machine-readable directly from the tag itself, without needing a separate lookup:
|
|
61
|
+
|
|
62
|
+
- `<!-- PROMOTED: E##_S##[_T##] -->` — the `_T##` task suffix is optional; use whichever level
|
|
63
|
+
the idea was actually promoted into (an epic, a story, or a specific task).
|
|
64
|
+
- `<!-- REJECTED -->` — stays bare, with no embedded ID. A rejection has no resulting board
|
|
65
|
+
item to point at.
|
|
66
|
+
|
|
67
|
+
Example (mirroring `project/todo.md`'s tagging style):
|
|
68
|
+
```
|
|
69
|
+
Add dark mode toggle to settings page <!-- PROMOTED: E12_S03 -->
|
|
70
|
+
Add a settings-page keyboard shortcut cheat sheet <!-- PROMOTED: E12_S03_T02 -->
|
|
71
|
+
Rewrite onboarding copy in a more casual tone <!-- REJECTED -->
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Source-Rapport Link Convention
|
|
75
|
+
|
|
76
|
+
Some ideas originate from a rapport rather than being manually captured via `/idea` — e.g. when
|
|
77
|
+
scrum-master's `rapport_review` step (E35_S03) detects a distinct idea surfaced inside a
|
|
78
|
+
problem rapport and, on user confirmation, appends it to `project/ideas.md` the same way
|
|
79
|
+
`/idea` does. When that happens, the entry's source rapport is recorded with a second inline
|
|
80
|
+
HTML comment on the same line:
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
<!-- rapport: <path/to/rapport.md> -->
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Rules:
|
|
87
|
+
- Written at capture time, alongside the idea text, by whichever flow is adding the entry
|
|
88
|
+
(scrum-master's rapport-derived capture path; `/idea`'s own manual capture never has a source
|
|
89
|
+
rapport and omits this comment entirely).
|
|
90
|
+
- Left in place through promotion/rejection — the `rapport:` comment and the terminal
|
|
91
|
+
`PROMOTED`/`REJECTED` comment coexist on the same line, e.g.:
|
|
58
92
|
```
|
|
59
|
-
|
|
60
|
-
Rewrite onboarding copy in a more casual tone <!-- DISCARDED -->
|
|
93
|
+
Extract shared retry logic into a utility <!-- rapport: project/rapports/problems/E40_S02_T01-segment-remarks.md --> <!-- PROMOTED: E61_S01 -->
|
|
61
94
|
```
|
|
95
|
+
- Consumed by the outcome-record mechanism at promotion/rejection time: if a `rapport:` comment
|
|
96
|
+
is present on the line, that rapport is updated with the decision (and `[SPIKE]`-prefixed in
|
|
97
|
+
its title/header if not already, per `templates/SCRUM_BOARD_SCHEMA.md`'s `[SPIKE]` section);
|
|
98
|
+
if absent (a manually-captured `/idea` entry with no source rapport), a
|
|
99
|
+
`project/documentation/plans/<slug>_PROMOTED.md` or `_REJECTED.md` file is created instead.
|
|
100
|
+
- Verified compatible with `scripts/idea_manager.sh`'s `real_entries()` filtering: that function
|
|
101
|
+
only strips lines whose first non-whitespace characters are `<!--`; a trailing inline comment
|
|
102
|
+
on an otherwise real entry line is untouched and the line still counts as a real entry.
|
|
103
|
+
|
|
104
|
+
No agent invoked by `/idea` applies terminal (`PROMOTED`/`REJECTED`) tags or acts on them — that
|
|
105
|
+
is reserved for the promotion step (e.g. within `/brainstorm`) and, for rapport-sourced ideas,
|
|
106
|
+
scrum-master's rapport-review flow.
|
|
107
|
+
|
|
108
|
+
### Outcome-Record Mechanism (`idea_manager.sh`) — E35_S03_T03
|
|
109
|
+
|
|
110
|
+
`scripts/idea_manager.sh` implements the tagging and outcome-record behavior described above, via
|
|
111
|
+
four additional subcommands beyond `add`/`list`:
|
|
112
|
+
|
|
113
|
+
- `tag "<idea-text>" <PROMOTED:E##_S##[_T##]|REJECTED>` — writes the terminal tag onto the
|
|
114
|
+
`project/ideas.md` line matching `<idea-text>` (an exact/literal match; errors if zero or more
|
|
115
|
+
than one line matches, and errors if the line is already tagged).
|
|
116
|
+
- `get-id "<idea-text>"` — prints the embedded board ID from that line's `PROMOTED` tag (errors
|
|
117
|
+
if the line has no `PROMOTED` tag).
|
|
118
|
+
- `get-rapport "<idea-text>"` — prints the `rapport:` path recorded on that line, or nothing
|
|
119
|
+
(exit 0) if the line has no source-rapport comment.
|
|
120
|
+
- `resolve "<idea-text>" <promoted|rejected> [board_id]` — the full outcome-record mechanism in
|
|
121
|
+
one call: tags the line (as `tag` does), then either updates the idea's source rapport or, if
|
|
122
|
+
none is recorded, creates the `project/documentation/plans/` fallback file:
|
|
123
|
+
- **Source rapport present:** the rapport's `# Rapport: ...` title line is prefixed
|
|
124
|
+
`[SPIKE] ` if not already, and an `## Idea Outcome Record` section (decision, date, resulting
|
|
125
|
+
board ID if promoted, and the idea text) is appended to the rapport file.
|
|
126
|
+
- **No source rapport:** `project/documentation/plans/<slug>_PROMOTED.md` or `_REJECTED.md` is
|
|
127
|
+
created (idea text slugified, lowercased, capped at 60 characters), containing the same
|
|
128
|
+
decision/date/board-ID/idea-text content.
|
|
129
|
+
|
|
130
|
+
`board_id` is required for `promoted` (validated to start with `E<digits>`) and must be omitted
|
|
131
|
+
for `rejected` (a rejection has no resulting board item).
|
|
62
132
|
|
|
63
|
-
|
|
133
|
+
This is the mechanism itself, not the trigger — nothing currently calls `resolve` automatically.
|
|
134
|
+
A future promotion step (e.g. within `/brainstorm`'s routing, or scrum-master acting on a
|
|
135
|
+
rapport-sourced idea) is expected to invoke it once that trigger exists.
|
|
@@ -50,7 +50,7 @@ Assess whether you have enough context to evaluate current behavior against the
|
|
|
50
50
|
Invoke the `/examplify` skill. Specify clearly what you want it to find out — e.g. which code paths are exercised, what inputs/outputs look like, or what edge cases exist.
|
|
51
51
|
|
|
52
52
|
### 5. Run `/evaluate`
|
|
53
|
-
Copy `.agents/skills/evaluate/assets/evaluation_invokation_template.yml` and fill in:
|
|
53
|
+
Copy `.agents/skills/j-evaluate/assets/evaluation_invokation_template.yml` and fill in:
|
|
54
54
|
- `paths`: path(s) to the relevant example files
|
|
55
55
|
- `goal`: the confirmed target goal
|
|
56
56
|
|
package/skills/j-init/SKILL.md
CHANGED
|
@@ -101,7 +101,7 @@ run can never silently relocate directories or edit `.gitignore`.
|
|
|
101
101
|
> `.agents/`/`.claude/` convention), was built and then withdrawn before release —
|
|
102
102
|
> testing found it left board resolution and session-end hooks writing to two
|
|
103
103
|
> different trees. It is not offered here. See
|
|
104
|
-
> `skills/distribute/CONFIG_SCHEMA.md` for the root-cause note and the tracked
|
|
104
|
+
> `skills/j-distribute/CONFIG_SCHEMA.md` for the root-cause note and the tracked
|
|
105
105
|
> follow-up to reintroduce it once fixed.
|
|
106
106
|
|
|
107
107
|
Carry the chosen value into step 4. Do not apply it yourself — the script owns all
|
|
@@ -116,7 +116,7 @@ framework scaffold (skill and agent definitions), which is a separate tree with
|
|
|
116
116
|
separate lifecycle — it gets overwritten wholesale by every `/distribute` run or npm
|
|
117
117
|
upgrade, unlike `project/`. Kept as its own flag (`scaffold_visibility`) rather than
|
|
118
118
|
folded into `project_files_visibility`'s enum; see
|
|
119
|
-
`skills/distribute/CONFIG_SCHEMA.md`'s "Scaffold visibility" section for the full
|
|
119
|
+
`skills/j-distribute/CONFIG_SCHEMA.md`'s "Scaffold visibility" section for the full
|
|
120
120
|
rationale.
|
|
121
121
|
|
|
122
122
|
Ask the user this question, verbatim, before running any script:
|
|
@@ -195,7 +195,7 @@ run) by the time `/init` runs `git add -A`.
|
|
|
195
195
|
If the script fails, check that you are in the project root and that git and `jq`
|
|
196
196
|
are available.
|
|
197
197
|
|
|
198
|
-
See `skills/distribute/CONFIG_SCHEMA.md` for the full `project_files_visibility` and
|
|
198
|
+
See `skills/j-distribute/CONFIG_SCHEMA.md` for the full `project_files_visibility` and
|
|
199
199
|
`scaffold_visibility` field reference.
|
|
200
200
|
|
|
201
201
|
### 5. Prompt next step
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"threshold_version":
|
|
2
|
+
"threshold_version": 3,
|
|
3
3
|
"inline_max_files": 3,
|
|
4
4
|
"inline_max_lines": 75,
|
|
5
5
|
"story_max_files": 5,
|
|
6
|
-
"bundle_lock_ttl_minutes": 30
|
|
6
|
+
"bundle_lock_ttl_minutes": 30,
|
|
7
|
+
"max_concurrent_developers": 3,
|
|
8
|
+
"max_concurrent_testers": 3,
|
|
9
|
+
"slot_ttl_minutes": 45
|
|
7
10
|
}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
# overwritten wholesale by every `/distribute` run or npm upgrade; project/
|
|
12
12
|
# is not). Filed as new, adjacent scope under E31_S07 rather than folded
|
|
13
13
|
# silently into project_files_visibility's existing enum. See
|
|
14
|
-
# skills/distribute/CONFIG_SCHEMA.md's "Scaffold visibility" section for the
|
|
14
|
+
# skills/j-distribute/CONFIG_SCHEMA.md's "Scaffold visibility" section for the
|
|
15
15
|
# full rationale.
|
|
16
16
|
#
|
|
17
17
|
# This is skills/j-init/'s own copy of skills/init/scripts/apply-scaffold-visibility.sh
|
|
@@ -30,7 +30,7 @@ fi
|
|
|
30
30
|
# queue/, rapports/, logs/). scaffold_visibility is a distinct, independent
|
|
31
31
|
# flag (E31_S07_T01, ported here in E31_S07_T03) covering the distributed
|
|
32
32
|
# .claude/.agents framework scaffold — kept separate per
|
|
33
|
-
# skills/distribute/CONFIG_SCHEMA.md's "Scaffold visibility" section, rather
|
|
33
|
+
# skills/j-distribute/CONFIG_SCHEMA.md's "Scaffold visibility" section, rather
|
|
34
34
|
# than folded into project_files_visibility's existing enum.
|
|
35
35
|
VISIBILITY="${JENGA_PROJECT_FILES_VISIBILITY:-visible}"
|
|
36
36
|
SCAFFOLD_VISIBILITY="${JENGA_SCAFFOLD_VISIBILITY:-visible}"
|
|
@@ -79,7 +79,7 @@ echo "→ Copying test-config.json from template..."
|
|
|
79
79
|
cp "$ASSETS_DIR/test-config_template.json" project/configs/test-config.json
|
|
80
80
|
|
|
81
81
|
# ─── 6.5. Create project/configs/scope-thresholds.json ───────────────────────
|
|
82
|
-
# Consumed by skills/jenga (Phase 0) and skills/do (Step 0); both halt if it's
|
|
82
|
+
# Consumed by skills/jenga (Phase 0) and skills/j-do (Step 0); both halt if it's
|
|
83
83
|
# missing, so it must exist immediately after scaffold.
|
|
84
84
|
echo "→ Copying scope-thresholds.json from template..."
|
|
85
85
|
cp "$ASSETS_DIR/scope-thresholds_template.json" project/configs/scope-thresholds.json
|
|
@@ -93,7 +93,7 @@ echo "→ Creating events.json..."
|
|
|
93
93
|
echo '[]' > project/logs/events.json
|
|
94
94
|
|
|
95
95
|
# ─── 8.5. Create project/knowledge-graph/{STUB_SCHEMA.md,graph.json} ─────────
|
|
96
|
-
# Consumed by skills/uncharted's conversational elicitation flow (`onboard`,
|
|
96
|
+
# Consumed by skills/j-uncharted's conversational elicitation flow (`onboard`,
|
|
97
97
|
# `segment --mode investigate`), which writes coarse graph nodes/edges to
|
|
98
98
|
# graph.json per the stub schema — both must exist before that flow's first
|
|
99
99
|
# write, per templates/KNOWLEDGE_GRAPH_STUB_SCHEMA_TEMPLATE.md's own header
|
|
@@ -138,4 +138,4 @@ git add -A
|
|
|
138
138
|
git commit -m "init: scaffold project structure and workflow config"
|
|
139
139
|
|
|
140
140
|
echo ""
|
|
141
|
-
echo "✓ Project scaffold complete."
|
|
141
|
+
echo "✓ Project scaffold complete."
|
|
@@ -265,7 +265,7 @@ Release-note rules:
|
|
|
265
265
|
- **`--output <path>`:** writes a standalone, disposable draft to that path instead (the pre-E36 behavior) — `CHANGELOG.md` is not touched in this mode.
|
|
266
266
|
- If no prior ledger-backed tag exists, a `--output` draft includes `> First release — full history included`; the standing `CHANGELOG.md` merge mode has no equivalent banner (it just merges full history into `[Unreleased]` like any other run).
|
|
267
267
|
- Scrum-board enrichment is best-effort only; missing or unreadable board data never fails the command.
|
|
268
|
-
- **`.publicignore` filtering:** when a repo-root `.publicignore` exists (the blocklist `/mirror-public` also reads), a candidate commit — or a completed task's associated commit(s), matched via the `task(E##_S##_T##):` commit-message convention — is dropped entirely when every changed file it touches is covered by that blocklist. A commit touching a mix of blocked and unblocked files is still logged normally; only full coverage excludes an entry. This exists because `CHANGELOG.md` itself is not blocklisted and ships to the public mirror, so an unfiltered entry referencing a private-only path (e.g. `project/board/`) would leak. Absent `.publicignore`, this is a strict no-op — unchanged from pre-E36_S02_T02 behavior. Matching reuses `skills/mirror-public/scripts/mirror.sh`'s `rsync --exclude-from` evaluation rather than a separate glob implementation, so a path classified "blocked" by `/mirror-public --dry-run` is classified "blocked" here too.
|
|
268
|
+
- **`.publicignore` filtering:** when a repo-root `.publicignore` exists (the blocklist `/mirror-public` also reads), a candidate commit — or a completed task's associated commit(s), matched via the `task(E##_S##_T##):` commit-message convention — is dropped entirely when every changed file it touches is covered by that blocklist. A commit touching a mix of blocked and unblocked files is still logged normally; only full coverage excludes an entry. This exists because `CHANGELOG.md` itself is not blocklisted and ships to the public mirror, so an unfiltered entry referencing a private-only path (e.g. `project/board/`) would leak. Absent `.publicignore`, this is a strict no-op — unchanged from pre-E36_S02_T02 behavior. Matching reuses `skills/j-mirror-public/scripts/mirror.sh`'s `rsync --exclude-from` evaluation rather than a separate glob implementation, so a path classified "blocked" by `/mirror-public --dry-run` is classified "blocked" here too.
|
|
269
269
|
|
|
270
270
|
## Ledger & Tagging
|
|
271
271
|
|
|
@@ -239,7 +239,12 @@ automated and human halves of the flow:
|
|
|
239
239
|
relies on the automated CI-staged test result) and then
|
|
240
240
|
`bash skills/j-publish/scripts/npm_stage_inspect.sh approve <stage-id> --otp <otp>`
|
|
241
241
|
from their own machine. `reject` (same script) is available to either
|
|
242
|
-
side to discard a staged candidate.
|
|
242
|
+
side to discard a staged candidate. On success, `approve` also generates
|
|
243
|
+
release notes into `CHANGELOG.md`'s `[Unreleased]` section and finalizes
|
|
244
|
+
it with the approved version — the same behavior described in
|
|
245
|
+
`adapters/npm.md`'s Staged Publishing section, shared by both target
|
|
246
|
+
types since it lives in `npm_stage_inspect.sh` itself, not in either
|
|
247
|
+
target-type-specific pipeline (E22_S09_T08).
|
|
243
248
|
- **Stage-id capture reads the CI run's own log, not a local `npm stage
|
|
244
249
|
list` call.** Because the actual `npm stage publish --provenance` call
|
|
245
250
|
runs inside the dispatched Actions run, the local `npm_stage_pipeline.sh`
|
|
@@ -119,7 +119,7 @@ becomes visible on the registry. See `skills/j-publish/SKILL.md`'s
|
|
|
119
119
|
|
|
120
120
|
- `bash skills/j-publish/scripts/npm_stage_pipeline.sh <target> <path-to-publish.json> [--dry-run] [--non-interactive] [--otp <otp>]` runs validate → gates → pack → stage → capture → ledger and writes a `staged` ledger entry.
|
|
121
121
|
- `bash skills/j-publish/scripts/npm_stage_inspect.sh test <stage-id>` installs the staged tarball into an isolated scratch directory and smoke-tests it, writing a `stage_tested` ledger entry.
|
|
122
|
-
- `bash skills/j-publish/scripts/npm_stage_inspect.sh approve <stage-id>` requires an npm 2FA one-time password and refuses without a passing `test` on record unless `--force <reason>` is given.
|
|
122
|
+
- `bash skills/j-publish/scripts/npm_stage_inspect.sh approve <stage-id>` requires an npm 2FA one-time password and refuses without a passing `test` on record unless `--force <reason>` is given. On a successful `npm stage approve`, it also generates release notes into `CHANGELOG.md`'s `[Unreleased]` section and finalizes that section with the approved version — the same `generate_release_notes.sh` + `finalize_changelog.sh` pair `/publish deploy` runs, reused rather than duplicated (E22_S09_T08). `--dry-run` skips this (it exits before the real approve call runs at all); a failed `npm stage approve` skips it too (no changelog write on a failed approve); `--force` still runs it — `--force` only bypasses the passing-test requirement, not the changelog step.
|
|
123
123
|
- `bash skills/j-publish/scripts/npm_stage_inspect.sh reject <stage-id>` discards the staged version.
|
|
124
124
|
|
|
125
125
|
Same registry-existence precondition as a normal `npm` publish: staged
|
|
@@ -76,7 +76,7 @@ git rev-parse --verify "$TO_REF" >/dev/null 2>&1 || {
|
|
|
76
76
|
# Absence of .publicignore is a strict no-op — PI_ACTIVE stays 0 and every
|
|
77
77
|
# _pi_* helper below fails open immediately.
|
|
78
78
|
#
|
|
79
|
-
# Matching semantics are borrowed from skills/mirror-public/scripts/mirror.sh
|
|
79
|
+
# Matching semantics are borrowed from skills/j-mirror-public/scripts/mirror.sh
|
|
80
80
|
# rather than reimplemented: that script's compute_ship_list asks rsync
|
|
81
81
|
# itself "what would transfer past --exclude-from=.publicignore?" and that
|
|
82
82
|
# is the single source of truth /mirror-public --dry-run reports as
|
|
@@ -86,6 +86,8 @@ fi
|
|
|
86
86
|
source "${SCRIPT_DIR}/publish_common.sh"
|
|
87
87
|
|
|
88
88
|
WRITE_LEDGER_SCRIPT="${SCRIPT_DIR}/write_ledger_entry.sh"
|
|
89
|
+
GENERATE_RELEASE_NOTES_SCRIPT="${SCRIPT_DIR}/generate_release_notes.sh"
|
|
90
|
+
FINALIZE_CHANGELOG_SCRIPT="${SCRIPT_DIR}/finalize_changelog.sh"
|
|
89
91
|
|
|
90
92
|
# ---------------------------------------------------------------------------
|
|
91
93
|
# OTP tracing guard — MUST run at the top level, before `main "$@"` is ever
|
|
@@ -397,6 +399,53 @@ _write_stage_tested_ledger() {
|
|
|
397
399
|
"${cmd[@]}" || log_warn "failed to write 'stage_tested' ledger entry for stage ${stage_id} (result: ${result})"
|
|
398
400
|
}
|
|
399
401
|
|
|
402
|
+
# _finalize_stage_changelog <target_name> <config_path> <package_version>
|
|
403
|
+
#
|
|
404
|
+
# `approve`'s equivalent of publish_deploy.sh's generate_release_notes() +
|
|
405
|
+
# finalize_changelog() pair (E22_S09_T08) — reused verbatim, not
|
|
406
|
+
# reimplemented. Only ever called AFTER a real `npm stage approve` call has
|
|
407
|
+
# already succeeded, so a failure here never masks (nor is masked by) the
|
|
408
|
+
# approve result itself; the caller decides how to report it.
|
|
409
|
+
#
|
|
410
|
+
# Mirrors publish_deploy.sh's resolve_last_tag(): resolves the last publish
|
|
411
|
+
# tag from the ledger via publish_resolve_last_publish_tag, never a
|
|
412
|
+
# hardcoded/guessed tag. Passes --from-tag only when a tag was actually
|
|
413
|
+
# resolved, and passes the config path positional only when one is
|
|
414
|
+
# resolved -- generate_release_notes.sh treats an omitted config the same
|
|
415
|
+
# way it treats an unresolved one internally (falls back to its own
|
|
416
|
+
# defaults via publish_resolve_history_file "").
|
|
417
|
+
#
|
|
418
|
+
# Uses the already-resolved package_version (from the stage's own `npm
|
|
419
|
+
# stage view` output) for finalize_changelog.sh, per the task's acceptance
|
|
420
|
+
# criteria -- never a re-derived version.
|
|
421
|
+
_finalize_stage_changelog() {
|
|
422
|
+
local target_name="$1" config_path="$2" package_version="$3"
|
|
423
|
+
local history_file last_tag
|
|
424
|
+
local -a notes_cmd=(bash "${GENERATE_RELEASE_NOTES_SCRIPT}" --target "${target_name}")
|
|
425
|
+
|
|
426
|
+
history_file="$(publish_resolve_history_file "${config_path}")"
|
|
427
|
+
last_tag="$(publish_resolve_last_publish_tag "${history_file}" HEAD 2>/dev/null || true)"
|
|
428
|
+
[[ -n "${last_tag}" ]] && notes_cmd+=(--from-tag "${last_tag}")
|
|
429
|
+
[[ -n "${config_path}" ]] && notes_cmd+=("${config_path}")
|
|
430
|
+
|
|
431
|
+
if ! "${notes_cmd[@]}"; then
|
|
432
|
+
log_warn "failed to generate release notes for stage approve (target: ${target_name})"
|
|
433
|
+
return 1
|
|
434
|
+
fi
|
|
435
|
+
|
|
436
|
+
if [[ -z "${package_version}" ]]; then
|
|
437
|
+
log_warn "no package version resolved from stage view — skipping CHANGELOG.md finalization"
|
|
438
|
+
return 1
|
|
439
|
+
fi
|
|
440
|
+
|
|
441
|
+
if ! bash "${FINALIZE_CHANGELOG_SCRIPT}" "${package_version}" "${REPO_ROOT}/CHANGELOG.md"; then
|
|
442
|
+
log_warn "failed to finalize CHANGELOG.md for stage approve (version: ${package_version})"
|
|
443
|
+
return 1
|
|
444
|
+
fi
|
|
445
|
+
|
|
446
|
+
return 0
|
|
447
|
+
}
|
|
448
|
+
|
|
400
449
|
# ---------------------------------------------------------------------------
|
|
401
450
|
# list [<package-spec>] [--config <path>] [--dry-run] [--json]
|
|
402
451
|
# ---------------------------------------------------------------------------
|
|
@@ -772,6 +821,18 @@ cmd_approve() {
|
|
|
772
821
|
exit "${EXIT_OP_FAILED}"
|
|
773
822
|
fi
|
|
774
823
|
|
|
824
|
+
# Generate release notes into CHANGELOG.md's [Unreleased] section and
|
|
825
|
+
# stamp it with the approved version — mirroring publish_deploy.sh's own
|
|
826
|
+
# generate_release_notes() + finalize_changelog() pair (E22_S09_T08).
|
|
827
|
+
# Only reached after a confirmed successful `npm stage approve` above, so
|
|
828
|
+
# a failed approve never gets a changelog write, and --force only ever
|
|
829
|
+
# affects the test-interlock check earlier in this function — this step
|
|
830
|
+
# runs identically on both the normal and --force paths, no divergent
|
|
831
|
+
# logic. Never reached at all under --dry-run, which already exited
|
|
832
|
+
# earlier, before the real approve call.
|
|
833
|
+
_finalize_stage_changelog "${target_name}" "${config_path}" "${package_version}" \
|
|
834
|
+
|| log_warn "stage ${stage_id} was approved, but CHANGELOG.md was not updated — see warnings above"
|
|
835
|
+
|
|
775
836
|
local -a ledger_cmd=(bash "${WRITE_LEDGER_SCRIPT}" "${target_name}" "${target_type}" approved "" --stage-id "${stage_id}")
|
|
776
837
|
[[ -n "${config_path}" ]] && ledger_cmd+=(--config "${config_path}")
|
|
777
838
|
[[ -n "${package_version}" ]] && ledger_cmd+=(--version "${package_version}")
|
|
@@ -3,7 +3,7 @@ name: j.reconcile
|
|
|
3
3
|
description: Polyfill alias of the reconcile skill under a collision-safe directory name. Identical behavior to /reconcile — Reconcile the scrum board with actual implementation state. Cross-checks every task's board status against git history and worktrees, merges orphaned worktree branches, demotes unimplemented "Done" items, promotes secretly-implemented items, flags code with no board provenance and offers /uncharted segment for it, and cleans stale entries from todo.md. Use when the board feels out of sync, after a big merge session, when tasks were completed outside the normal workflow, or when todo.md has grown stale. Trigger on phrases like "sync the board", "clean up the board", "reconcile", "board is out of date", "todo is stale", or "check what's really done". Use when the bare /reconcile form is shadowed by another tool's own built-in command of the same name.
|
|
4
4
|
metadata:
|
|
5
5
|
prefered_agent: scrum-master
|
|
6
|
-
output_types:
|
|
6
|
+
output_types: id_list
|
|
7
7
|
keywords:
|
|
8
8
|
- j-reconcile
|
|
9
9
|
- polyfill
|
|
@@ -200,7 +200,7 @@ older conventions still present in this repo's history (`E04_S01: ...` and
|
|
|
200
200
|
`feat(train): implement E01_S05 - ...`).
|
|
201
201
|
|
|
202
202
|
The script reuses the board-linkage check from
|
|
203
|
-
`skills/uncharted/scripts/resolve-segment-target.sh` through its batch interface. Do not
|
|
203
|
+
`skills/j-uncharted/scripts/resolve-segment-target.sh` through its batch interface. Do not
|
|
204
204
|
re-derive linkage yourself, and do not substitute a `grep` over `project/board/` if the script
|
|
205
205
|
fails — a second answer to "is this path on the board" is what that reuse exists to prevent.
|
|
206
206
|
If the script exits non-zero, report the failure in the reconcile report and continue to phase 6.
|