@jenga-ai/agent 1.2.4 → 2.0.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.
Files changed (100) hide show
  1. package/README.md +97 -91
  2. package/agents/developer.md +26 -7
  3. package/agents/scrum-master.md +57 -22
  4. package/agents/tester.md +68 -4
  5. package/hooks/on_session_end.sh +40 -1
  6. package/lib/generate-agent-context.js +18 -1
  7. package/lib/generate-copilot-instructions.js +18 -1
  8. package/lib/generate-skill-allow-list.js +191 -0
  9. package/lib/skill-allow-list.json +43 -0
  10. package/package.json +35 -20
  11. package/scripts/apply-j-prefix.sh +230 -0
  12. package/scripts/consume-context-digest.sh +103 -0
  13. package/scripts/postinstall.js +25 -0
  14. package/scripts/sweep-stale-context-digests.sh +132 -0
  15. package/scripts/validate-board.sh +5 -0
  16. package/scripts/write-context-digest.sh +230 -0
  17. package/skills/brainstorm/SKILL.md +1 -1
  18. package/skills/btw/SKILL.md +1 -1
  19. package/skills/clearify/SKILL.md +1 -1
  20. package/skills/close-story/SKILL.md +78 -6
  21. package/skills/close-story/scripts/check-privatized.sh +345 -0
  22. package/skills/commit/SKILL.md +12 -2
  23. package/skills/continue/SKILL.md +1 -1
  24. package/skills/deep-dive/SKILL.md +1 -1
  25. package/skills/dev-done/SKILL.md +46 -0
  26. package/skills/dev-done/scripts/classify-commit-outcome.sh +114 -0
  27. package/skills/distribute/SKILL.md +1 -1
  28. package/skills/do/SKILL.md +100 -10
  29. package/skills/doc/README.md +155 -0
  30. package/skills/doc/SKILL.md +43 -13
  31. package/skills/doc/authoring-notes.md +72 -0
  32. package/skills/doc/scripts/resolve_last_update.py +149 -0
  33. package/skills/doc-sync/SKILL.md +1 -1
  34. package/skills/dooo/SKILL.md +1 -1
  35. package/skills/error/SKILL.md +1 -1
  36. package/skills/evaluate/SKILL.md +1 -1
  37. package/skills/examplify/SKILL.md +1 -1
  38. package/skills/help/SKILL.md +1 -1
  39. package/skills/idea/SKILL.md +1 -1
  40. package/skills/improve/SKILL.md +1 -1
  41. package/skills/init/SKILL.md +8 -7
  42. package/skills/init/assets/scope-thresholds_template.json +7 -0
  43. package/skills/init/scripts/init.sh +6 -0
  44. package/skills/j-init/SKILL.md +168 -0
  45. package/skills/j-init/assets/.gitignore_template +15 -0
  46. package/skills/j-init/assets/PROJECT_SUMMARY_template.md +13 -0
  47. package/skills/j-init/assets/directory_structure.txt +14 -0
  48. package/skills/j-init/assets/scope-thresholds_template.json +7 -0
  49. package/skills/j-init/assets/strategy_stub_template.md +38 -0
  50. package/skills/j-init/assets/test-config_template.json +4 -0
  51. package/skills/j-init/assets/workflow_template.json +30 -0
  52. package/skills/j-init/scripts/apply-project-visibility.sh +176 -0
  53. package/skills/j-init/scripts/detect-existing-codebase.sh +166 -0
  54. package/skills/j-init/scripts/init.sh +116 -0
  55. package/skills/jbp/SKILL.md +1 -1
  56. package/skills/jenga/SKILL.md +1 -1
  57. package/skills/jenga/scripts/render-confirmation.sh +55 -18
  58. package/skills/jenga-permission-level/SKILL.md +1 -1
  59. package/skills/lgtm/SKILL.md +1 -1
  60. package/skills/pi-plan/SKILL.md +1 -1
  61. package/skills/proceed/SKILL.md +1 -1
  62. package/skills/publish/SKILL.md +67 -1
  63. package/skills/publish/adapters/npm-ci.md +60 -4
  64. package/skills/publish/adapters/npm.md +18 -0
  65. package/skills/publish/assets/ci-contract.md +27 -0
  66. package/skills/publish/assets/publish.example.json +27 -0
  67. package/skills/publish/schemas/publish.schema.json +20 -0
  68. package/skills/publish/scripts/npm_ci_pipeline.sh +50 -1
  69. package/skills/publish/scripts/npm_stage_inspect.sh +829 -0
  70. package/skills/publish/scripts/npm_stage_pipeline.sh +427 -0
  71. package/skills/publish/scripts/publish_common.sh +16 -0
  72. package/skills/publish/scripts/show_history.sh +12 -5
  73. package/skills/publish/scripts/validate_npm_stage_env.sh +184 -0
  74. package/skills/publish/scripts/write_ledger_entry.sh +92 -2
  75. package/skills/reconcile/SKILL.md +122 -12
  76. package/skills/reconcile/assets/report_format.md +17 -0
  77. package/skills/reconcile/scripts/resolve-reconcile-scope.sh +489 -0
  78. package/skills/reconcile-origin/SKILL.md +1 -1
  79. package/skills/redo/SKILL.md +1 -1
  80. package/skills/skillify/SKILL.md +1 -1
  81. package/skills/spinoff/SKILL.md +1 -1
  82. package/skills/status/SKILL.md +1 -1
  83. package/skills/todo/SKILL.md +40 -3
  84. package/skills/todo/scripts/add_trivial_task.sh +216 -0
  85. package/skills/todo/scripts/update_story_tasks.py +87 -0
  86. package/skills/uncharted/SKILL.md +201 -22
  87. package/skills/uncharted/scripts/directory-triage.sh +342 -0
  88. package/skills/uncharted/scripts/elicitation-state.sh +457 -0
  89. package/skills/wtf/SKILL.md +1 -1
  90. package/templates/SCRUM_BOARD_SCHEMA.md +90 -2
  91. package/templates/agent-context.md.tpl +47 -12
  92. package/templates/copilot-instructions.md.tpl +36 -9
  93. package/mcp/router/README.md +0 -19
  94. package/mcp/router/embedder.js +0 -23
  95. package/mcp/router/index.js +0 -204
  96. package/mcp/router/matcher.js +0 -87
  97. package/mcp/router/package-lock.json +0 -1048
  98. package/mcp/router/package.json +0 -11
  99. package/mcp/router/skill-index.js +0 -104
  100. package/skills/route/SKILL.md +0 -180
@@ -0,0 +1,216 @@
1
+ #!/usr/bin/env bash
2
+ # skills/todo/scripts/add_trivial_task.sh
3
+ #
4
+ # Creates a fully-formed task board file for a `/todo --trivial` mission,
5
+ # forced to execution_scope: inline unconditionally, and registers it both
6
+ # in its parent story's tasks: frontmatter list and in project/todo.md.
7
+ #
8
+ # This script performs only the MECHANICAL half of --trivial: templating the
9
+ # task file, assigning the next task number, and wiring it into the board.
10
+ # The JUDGMENT half — estimating file/line counts and deciding what
11
+ # execution_scope the normal heuristic in agents/scrum-master.md would have
12
+ # assigned (computed_tier) — happens in the calling agent's instructions
13
+ # (skills/todo/SKILL.md), per the Skill Implementation Principle: a step that
14
+ # requires reasoning about branching logic, new dependencies, etc. does not
15
+ # belong in a script. This script never reads project/configs/scope-thresholds.json
16
+ # or recomputes computed_tier itself — it only records what it was told.
17
+ #
18
+ # Usage:
19
+ # add_trivial_task.sh --story <E##_S##> --title "<title>" \
20
+ # --description "<description>" --criteria "<c1>|<c2>|..." \
21
+ # --computed-tier <inline|task|story> --est-files <N> --est-lines <M> \
22
+ # [--prerequisites "<text>"]
23
+ #
24
+ # Requires an ALREADY-EXISTING parent story file (--trivial does not create
25
+ # stories or epics — resolve/create those first via the normal /todo flow).
26
+ #
27
+ # On success, prints the new task ID (e.g. E32_S14_T05) to stdout and exits 0.
28
+
29
+ set -euo pipefail
30
+
31
+ REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
32
+ cd "$REPO_ROOT"
33
+
34
+ TASKS_DIR="project/board/tasks"
35
+ STORIES_DIR="project/board/stories"
36
+ UPDATE_STORY_SCRIPT="skills/todo/scripts/update_story_tasks.py"
37
+
38
+ story_id=""
39
+ title=""
40
+ description=""
41
+ criteria=""
42
+ computed_tier=""
43
+ est_files=""
44
+ est_lines=""
45
+ prerequisites="None."
46
+
47
+ usage() {
48
+ cat >&2 <<EOF
49
+ Usage: $0 --story <E##_S##> --title "<title>" --description "<description>" \\
50
+ --criteria "<c1>|<c2>|..." --computed-tier <inline|task|story> \\
51
+ --est-files <N> --est-lines <M> [--prerequisites "<text>"]
52
+ EOF
53
+ exit 1
54
+ }
55
+
56
+ while [ $# -gt 0 ]; do
57
+ case "$1" in
58
+ --story) story_id="$2"; shift 2 ;;
59
+ --title) title="$2"; shift 2 ;;
60
+ --description) description="$2"; shift 2 ;;
61
+ --criteria) criteria="$2"; shift 2 ;;
62
+ --computed-tier) computed_tier="$2"; shift 2 ;;
63
+ --est-files) est_files="$2"; shift 2 ;;
64
+ --est-lines) est_lines="$2"; shift 2 ;;
65
+ --prerequisites) prerequisites="$2"; shift 2 ;;
66
+ -h|--help) usage ;;
67
+ *) echo "Error: unknown argument '$1'" >&2; usage ;;
68
+ esac
69
+ done
70
+
71
+ for req_name in story_id title description criteria computed_tier est_files est_lines; do
72
+ if [ -z "${!req_name}" ]; then
73
+ echo "Error: --${req_name//_/-} is required" >&2
74
+ exit 1
75
+ fi
76
+ done
77
+
78
+ if ! [[ "$story_id" =~ ^E[0-9]+_S[0-9]+$ ]]; then
79
+ echo "Error: --story must look like E##_S## (got '$story_id')" >&2
80
+ exit 1
81
+ fi
82
+
83
+ case "$computed_tier" in
84
+ inline|task|story) ;;
85
+ *) echo "Error: --computed-tier must be one of: inline, task, story (got '$computed_tier')" >&2; exit 1 ;;
86
+ esac
87
+
88
+ case "$est_files" in
89
+ ''|*[!0-9]*) echo "Error: --est-files must be a non-negative integer (got '$est_files')" >&2; exit 1 ;;
90
+ esac
91
+ case "$est_lines" in
92
+ ''|*[!0-9]*) echo "Error: --est-lines must be a non-negative integer (got '$est_lines')" >&2; exit 1 ;;
93
+ esac
94
+
95
+ epic_id="${story_id%%_S*}"
96
+
97
+ # Locate the parent story file. --trivial requires it to already exist.
98
+ story_file=""
99
+ for f in "${STORIES_DIR}/${story_id}_"*.md; do
100
+ if [ -f "$f" ]; then
101
+ story_file="$f"
102
+ break
103
+ fi
104
+ done
105
+ if [ -z "$story_file" ]; then
106
+ echo "Error: no story file found for $story_id under $STORIES_DIR/. --trivial requires an already-resolved story — create it via the normal /todo flow first." >&2
107
+ exit 1
108
+ fi
109
+
110
+ if [ ! -f "$UPDATE_STORY_SCRIPT" ]; then
111
+ echo "Error: $UPDATE_STORY_SCRIPT not found." >&2
112
+ exit 1
113
+ fi
114
+
115
+ # Determine the next task number for this story by scanning existing task files.
116
+ max_num=0
117
+ shopt -s nullglob
118
+ for f in "${TASKS_DIR}/${story_id}_T"*.md; do
119
+ base="$(basename "$f")"
120
+ num="$(printf '%s' "$base" | sed -nE "s/^${story_id}_T([0-9]+)_.*/\1/p")"
121
+ if [ -n "$num" ]; then
122
+ num=$((10#$num))
123
+ if [ "$num" -gt "$max_num" ]; then
124
+ max_num=$num
125
+ fi
126
+ fi
127
+ done
128
+ shopt -u nullglob
129
+ next_num=$((max_num + 1))
130
+ next_num_padded="$(printf '%02d' "$next_num")"
131
+ task_id="${story_id}_T${next_num_padded}"
132
+
133
+ shopt -s nullglob
134
+ existing_matches=("${TASKS_DIR}/${task_id}_"*.md)
135
+ shopt -u nullglob
136
+ if [ "${#existing_matches[@]}" -gt 0 ]; then
137
+ echo "Error: a task file for $task_id already exists (ID collision). Aborting." >&2
138
+ exit 1
139
+ fi
140
+
141
+ # Slugify the title for the filename.
142
+ slug="$(printf '%s' "$title" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9]+/-/g; s/^-+//; s/-+$//')"
143
+ slug="${slug:0:60}"
144
+ slug="${slug%-}"
145
+ if [ -z "$slug" ]; then
146
+ slug="trivial-task"
147
+ fi
148
+
149
+ today="$(date -u +%Y-%m-%d)"
150
+
151
+ scope_rationale="forced inline via --trivial; computed scope would have been '${computed_tier}' — estimated ${est_files} files, ~${est_lines} lines"
152
+ override_justification="/todo --trivial invoked by user on ${today}; execution_scope forced to 'inline', overriding the heuristic's computed '${computed_tier}' tier (see scope_rationale)."
153
+
154
+ # Build the Acceptance Criteria block from the pipe-separated --criteria value.
155
+ criteria_block=""
156
+ IFS='|' read -ra crit_arr <<< "$criteria"
157
+ for c in "${crit_arr[@]}"; do
158
+ c_trimmed="$(printf '%s' "$c" | sed -E 's/^[[:space:]]+//; s/[[:space:]]+$//')"
159
+ if [ -n "$c_trimmed" ]; then
160
+ criteria_block+="- [ ] ${c_trimmed}"$'\n'
161
+ fi
162
+ done
163
+ if [ -z "$criteria_block" ]; then
164
+ echo "Error: --criteria produced no usable acceptance criteria" >&2
165
+ exit 1
166
+ fi
167
+
168
+ task_file="${TASKS_DIR}/${task_id}_${slug}.md"
169
+
170
+ cat > "$task_file" <<EOF
171
+ ---
172
+ id: ${task_id}
173
+ story_id: ${story_id}
174
+ epic_id: ${epic_id}
175
+ title: ${title}
176
+ status: Pending
177
+ date_created: ${today}
178
+ date_started:
179
+ date_completed:
180
+ dates_previously_completed:
181
+ reopened_on:
182
+ reopened_reason:
183
+ assigned_to: developer
184
+ docs: []
185
+ execution_scope: inline
186
+ needs_docs: false
187
+ scope_rationale: "${scope_rationale}"
188
+ jenga_assigned: false
189
+ override_justification: "${override_justification}"
190
+ ---
191
+
192
+ # Task: ${title}
193
+
194
+ ## Description
195
+ ${description}
196
+
197
+ ## Prerequisites
198
+ ${prerequisites}
199
+
200
+ ## Acceptance Criteria
201
+ ${criteria_block}
202
+ EOF
203
+
204
+ echo "Wrote task file: ${task_file}"
205
+
206
+ # Register the new task under its parent story's tasks: frontmatter list.
207
+ if ! scripts/with-lock.sh "$story_file" -- python3 "$UPDATE_STORY_SCRIPT" "$story_file" "$task_id"; then
208
+ echo "Error: failed to register ${task_id} in ${story_file}'s tasks: list (lock timeout or write failure)." >&2
209
+ exit 1
210
+ fi
211
+
212
+ # Register the todo entry using the FULL task ID, so /do routes straight into
213
+ # its Inline Execution Path without a redundant breakdown pass.
214
+ bash scripts/todo_manager.sh add "${title}: ${task_id}"
215
+
216
+ echo "${task_id}"
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ skills/todo/scripts/update_story_tasks.py
4
+
5
+ Mechanically inserts a task ID into a story board file's `tasks:` frontmatter
6
+ list, if it is not already present. Idempotent (a re-run with the same
7
+ task_id is a no-op, exit 0).
8
+
9
+ This is a pure text/frontmatter edit and does no board-wide validation beyond
10
+ "frontmatter block exists" — it is intended to be invoked already wrapped in
11
+ scripts/with-lock.sh, keyed to the story file, per templates/SCRUM_BOARD_SCHEMA.md's
12
+ File Locking section (board frontmatter writes must go through the lock wrapper).
13
+
14
+ Usage:
15
+ python3 skills/todo/scripts/update_story_tasks.py <story-file> <task-id>
16
+
17
+ Exit codes:
18
+ 0 success (task_id inserted, or already present)
19
+ 1 usage error
20
+ 2 story file has no parseable frontmatter block
21
+ """
22
+ import sys
23
+
24
+
25
+ def main() -> int:
26
+ if len(sys.argv) != 3:
27
+ print("Usage: update_story_tasks.py <story-file> <task-id>", file=sys.stderr)
28
+ return 1
29
+
30
+ path, task_id = sys.argv[1], sys.argv[2]
31
+
32
+ with open(path, "r", encoding="utf-8") as f:
33
+ content = f.read()
34
+
35
+ parts = content.split("---", 2)
36
+ if len(parts) < 3:
37
+ print(f"Error: {path} has no valid '---' frontmatter block", file=sys.stderr)
38
+ return 2
39
+
40
+ _, frontmatter, rest = parts
41
+ lines = frontmatter.split("\n")
42
+ task_line = f" - {task_id}"
43
+
44
+ if any(line.strip() == task_line.strip() for line in lines):
45
+ print(f"No-op: {task_id} already present in {path}'s tasks: list")
46
+ return 0
47
+
48
+ idx = None
49
+ inline_empty_idx = None
50
+ for i, line in enumerate(lines):
51
+ stripped = line.strip()
52
+ if stripped == "tasks:":
53
+ idx = i
54
+ break
55
+ if stripped == "tasks: []":
56
+ inline_empty_idx = i
57
+ break
58
+
59
+ if inline_empty_idx is not None:
60
+ lines[inline_empty_idx] = "tasks:"
61
+ lines.insert(inline_empty_idx + 1, task_line)
62
+ elif idx is not None:
63
+ j = idx + 1
64
+ while j < len(lines) and lines[j].strip().startswith("- "):
65
+ j += 1
66
+ lines.insert(j, task_line)
67
+ else:
68
+ # No tasks: key found at all — append one at the end of the frontmatter,
69
+ # trimming any single trailing blank line first so formatting stays tidy.
70
+ if lines and lines[-1].strip() == "":
71
+ lines.pop()
72
+ lines.append("tasks:")
73
+ lines.append(task_line)
74
+ lines.append("")
75
+
76
+ new_frontmatter = "\n".join(lines)
77
+ new_content = "---" + new_frontmatter + "---" + rest
78
+
79
+ with open(path, "w", encoding="utf-8") as f:
80
+ f.write(new_content)
81
+
82
+ print(f"Updated {path}: added {task_id} to tasks:")
83
+ return 0
84
+
85
+
86
+ if __name__ == "__main__":
87
+ sys.exit(main())
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: uncharted
2
+ name: j:uncharted
3
3
  description: Investigate code that has no Jenga board provenance — a foreign file, an external source being pulled in, or an entire pre-existing codebase — and give it a consistent understanding document plus proper board representation.
4
4
  metadata:
5
5
  prefered_agent: scrum-master
@@ -47,9 +47,9 @@ Every mode runs the same shared investigative engine and emits the same understa
47
47
 
48
48
  | Mode | Scale | What it does | Implemented by |
49
49
  |---|---|---|---|
50
- | `segment` | one file, directory, or feature | Analyses a target that is already in the repo (or has just been imported), then proposes a standard epic/story/task so the segment gains normal board provenance. | E40_S02 |
50
+ | `segment` | one file, directory, or feature | Two explicit modes since E20_S08_T03: `--mode delivery` (default, unchanged) analyses a target already in the repo and proposes a standard epic/story/task; `--mode investigate` opens a conversational architecture-investigation flow instead. See **`segment`** below for the mode choice. | E40_S02 / E20_S08_T03 |
51
51
  | `import` | an external source | Acquires a git URL, an out-of-repo path, or a pasted snippet into the repo at a user-confirmed location, then hands off to `segment`. | E40_S03 |
52
- | `onboard` | the whole codebase | Coarse-first pass over an existing project at framework-adoption time. Produces a capped set of **backfilled** epics. Board-only — never touches application code. | E40_S04 |
52
+ | `onboard` | the whole codebase | Conversational by default since E20_S08_T03: discovery scripts seed a human-in-the-loop elicitation that writes `[ARCH]`-tagged board items and coarse graph nodes. `--legacy` reproduces the original fully-automated, zero-prompt, capped-**backfilled**-epic pass unchanged. Board/graph-only — never touches application code, in either mode. | E40_S04 / E20_S08_T03 |
53
53
 
54
54
  **Dispatch rules:**
55
55
 
@@ -146,6 +146,111 @@ A document whose judgement sections are generic enough to apply to any codebase
146
146
 
147
147
  ---
148
148
 
149
+ ## Conversational Elicitation
150
+
151
+ Since **E20_S08_T03**, `onboard`'s default behavior and `segment --mode investigate` both run a human-in-the-loop **conversational elicitation** instead of (or, for `onboard`, in addition to keeping available) a one-shot deterministic pass. This section defines the mechanics shared by both; each mode's own subsection below only describes what is specific to it.
152
+
153
+ **What conversational elicitation produces, and how that differs from the Understanding Document above:** the **primary** output is coarse-tier graph nodes/edges — written directly to `project/knowledge-graph/graph.json`, conforming to the stub schema at `project/knowledge-graph/STUB_SCHEMA.md` (E20_S08_T01; this is a throwaway pilot schema, swapped wholesale once E20_S01's real schema lands — do not extend it expecting stability). Every node this flow writes carries `source: "human"`, since it comes from a person confirming or correcting a proposed understanding, not from mechanical extraction. Board representation is a `[ARCH]`-tagged epic, story, or task at whichever level fits the investigated scope (see `templates/SCRUM_BOARD_SCHEMA.md`'s `[ARCH]` — Durable Architectural Inventory convention) — **not** the delivery-shaped epic/story/task proposal `segment --mode delivery` and legacy `onboard` produce, and not the fixed 7-heading Understanding Document either. A written summary is produced only when warranted, filed as the resulting board item's ordinary `-summary.md` — there is no new artifact type or separate "Understanding Document" for conversational output.
154
+
155
+ ### Human-Oracle-Availability Limitation
156
+
157
+ **Read this before running a conversational elicitation on code nobody currently understands.** This is `/uncharted`'s own documented, standing, accepted limitation — not only `agents/developer.md`'s and `agents/tester.md`'s (E20_S08_T02 covers those; this is the skill's own copy of the same limitation, since the person driving `/uncharted` may never open either agent file directly).
158
+
159
+ For genuinely undocumented code, there is often no reliable human oracle to confirm or correct a proposed understanding — the person answering may not know either, or may confidently confirm a wrong answer. Per the parent story's own scrutiny (scored 3/10 on this exact point) and its solution assessment's disposition ("Accept and Descope" on Problem 1): **conversational elicitation does not solve this, and does not claim to.** It is a complementary path for codebases where *some* human context exists, not a fix for the hardest, genuinely zero-oracle case.
160
+
161
+ - **The deterministic pipeline remains the tool of record for zero-oracle codebases.** `onboard --legacy` and `segment --mode delivery` never depend on anyone confirming intent — they ground everything in mechanical evidence (file structure, dependencies, test coverage) and say so explicitly under `Open Questions` when the evidence doesn't support a conclusion. When there is no one left who understands the code, reach for one of those, not the conversational flow.
162
+ - **When running the conversational flow, do not manufacture confidence.** If the user's answer is uncertain, hedged, or contradicts what discovery/Investigative Mode found, write the node honestly — do not round an uncertain answer up to a confirmed one. There is no schema field yet to tag confidence (the stub schema is intentionally minimal); until one exists, say so in the node's `description` text itself (e.g. "per the user, this module retries failed charges — unconfirmed against the code, which shows only a single retry attempt") rather than silently dropping the caveat.
163
+ - **A confidently wrong answer is not detectable by this flow.** Corroboration against a second signal (commit history, existing docs, a second person) is the only mitigation, and it is not built here — this is the accepted residual risk, not a gap to engineer around mid-conversation.
164
+
165
+ ### Directory Triage
166
+
167
+ Runs once per elicitation, between discovery and the first Investigative Mode dispatch — never skipped, and never silently absorbed into the convergence loop below, because triaging noise out is exactly what keeps that loop from wasting turns (and the user's attention) on vendor/generated directories nobody wants a graph node for.
168
+
169
+ **Step 1 — deterministic pass.** Feed the candidate directories (from `discover-subsystems.sh`'s output for `onboard`, or the target's immediate subdirectories for `segment --mode investigate`) to:
170
+
171
+ ```bash
172
+ discover-subsystems.sh <root> | jq -r '.candidates[].path' \
173
+ | bash skills/uncharted/scripts/directory-triage.sh <root>
174
+ ```
175
+
176
+ Read `ignored` (already excluded by `.gitignore`, or matching the fixed vendor/generated pattern list — see the script's own header for the full list) and `remaining`. This is a mechanical classification; do not second-guess it or re-run judgement over an `ignored` entry.
177
+
178
+ **Step 2 — judgement pass over `remaining`.** This is the generalize-list the deterministic pattern list can never catch: content-based cases where a directory is legitimately noise or a single coarse unit for reasons a pattern match cannot see — the task's own example is "this directory is SOAP request mock-ups for a test suite." Skim `remaining` (directory names, a shallow listing, README/comment hints) and propose, for each one that looks like a generalize candidate, a single-sentence rationale and the disposition: **exclude** (like `ignored`, zero graph nodes) or **generalize** (one coarse-tier node covering the whole directory, no per-file drill-down, no Investigative Mode dispatch into it). Everything not proposed for either disposition proceeds to full investigation.
179
+
180
+ **Step 3 — one confirmation gate, both lists together.** Per the task's own acceptance criterion, both the deterministic ignore-list and the judgement-based generalize-list are confirmed with the user **before any developer/tester Investigative Mode dispatch** — not after, and not as two separate gates:
181
+
182
+ ```
183
+ Directory triage for <target>:
184
+
185
+ Excluded (pattern/gitignore match) — N directories:
186
+ <path> — <reason>
187
+ ...
188
+
189
+ Proposed for exclusion or generalization (judgement) — M directories:
190
+ <path> — exclude|generalize — <one-line rationale>
191
+ ...
192
+
193
+ Everything else (K directories) proceeds to investigation.
194
+
195
+ How should this be applied?
196
+ 1. Accept as proposed
197
+ 2. Revise — change a disposition before proceeding
198
+ 3. Show me the full excluded/generalize lists in detail
199
+ 4. Other (describe below)
200
+ ```
201
+
202
+ Silence, a counter-question, or an ambiguous reply is not consent — re-ask, the same convention used at every other confirmation gate in this skill. Option 3 does not count as a decision; re-present the same choice after showing the detail. Checkpoint the confirmed triage result immediately via `elicitation-state.sh checkpoint` (see Multi-Session Persistence below) so a paused-and-resumed session never re-asks a question the user already answered.
203
+
204
+ ### Convergence Loop
205
+
206
+ Runs once per surviving candidate (a subsystem, a named flow, a directory) after Directory Triage. This is the "propose understanding, ask the user to confirm or correct" cycle at the center of the redesign — and the one the scrutiny flagged as having no termination bound and no defense against confirmation fatigue. Both gaps are closed mechanically, not by agent discipline alone:
207
+
208
+ 1. **Dispatch Investigative Mode.** Per `agents/developer.md`'s and `agents/tester.md`'s Investigative Mode sections (E20_S08_T02), dispatch the developer to trace what the code actually does for the candidate, and the tester to trace what the test suite actually exercises and verifies for the same candidate — two distinct vantage points, not two names for the same read. Both are read-only, worktree-sandboxed, no commits, no board writes.
209
+ 2. **Propose understanding.** From both traces, draft the candidate's coarse graph node(s)/edge(s) (per the stub schema) and a plain-language summary of what they represent.
210
+ 3. **Risk-weighted gating — not every finding gets a prompt.** This is the fix for confirmation fatigue (solution assessment, Problem 6, Solution B — RECOMMENDED): force an explicit confirmation only for **high-uncertainty or high-impact** findings — a node whose description depends on an inference the traces don't fully support, a node with many outgoing edges (structurally central), or one the Human-Oracle-Availability Limitation above already flagged as uncertain. **Auto-accept** low-risk, high-confidence findings — the traces agree, the finding is narrow in scope, nothing about it is surprising — without a prompt, but **log every auto-accepted node** in the elicitation state's checkpoint data (see below) so the decision is auditable later, per that solution's own mitigation for "the scoring mechanism itself misjudges impact."
211
+ 4. **Confirm/correct, one round per call to `elicitation-state.sh turn`.** For a node requiring confirmation, present the draft and ask the user to confirm or correct it (per the Interaction Pattern in `CLAUDE.md` — confirm / correct-with-detail / defer as "unconfirmed" / other). Each round, call:
212
+
213
+ ```bash
214
+ bash skills/uncharted/scripts/elicitation-state.sh turn --id <elicitation-id> --node <node-id>
215
+ ```
216
+
217
+ Exit `0` means keep looping (cap not yet reached) if the user corrected rather than confirmed. Exit `3` means **the hard turn cap has been reached** — the node is now marked `flagged` in the state file. **Do not loop again on that node.** Instead present it as unresolved and offer an explicit choice rather than looping indefinitely (solution assessment, Problem 10, Solution A — RECOMMENDED):
218
+
219
+ ```
220
+ <node> has reached the confirmation round limit without converging.
221
+ 1. Accept the current best draft as-is (flagged low-confidence)
222
+ 2. Defer — skip this node for now, continue with the rest
223
+ 3. Continue past the limit (explicit override)
224
+ 4. Other (describe below)
225
+ ```
226
+
227
+ Option 3 is the only way past the cap, and it is a per-node, explicit, one-time override — it does not raise the cap for the rest of the run.
228
+ 5. **On convergence** (confirmed, corrected-and-accepted, or resolved via the cap choice above), call:
229
+
230
+ ```bash
231
+ bash skills/uncharted/scripts/elicitation-state.sh converge --id <elicitation-id> --node <node-id> --note "<one-line summary of what was confirmed>"
232
+ ```
233
+
234
+ then write the node/edge to `project/knowledge-graph/graph.json` per the stub schema, and checkpoint the elicitation state (next section) — **after every converged node**, not only at the end of the whole run.
235
+
236
+ ### Multi-Session Persistence
237
+
238
+ A whole-codebase `onboard` conversation, or an investigation of a large directory, can span more sessions than fit in one sitting. State persists via the existing `SessionEnd`/queue infrastructure — no new persistence mechanism (solution assessment, Problem 11, Solution A — RECOMMENDED).
239
+
240
+ - **`init` once, at the start of an elicitation:**
241
+
242
+ ```bash
243
+ bash skills/uncharted/scripts/elicitation-state.sh init --id <elicitation-id> --target "<path or description>" --cap 5
244
+ ```
245
+
246
+ Idempotent — safe to call again on a resumed `<elicitation-id>` without resetting progress. Choose `<elicitation-id>` so it is stable and re-derivable across sessions (e.g. `onboard-<root-slug>-<date>`, or `segment-investigate-<target-slug>`), since a resuming session must be able to reconstruct it to call `init` again.
247
+ - **`checkpoint` after every converged node and after the Directory Triage confirmation gate** — never only at the end. This is what makes a mid-run pause lossless: `checkpoint --id <id> --json <file>` merges arbitrary progress data (triage results, draft nodes not yet converged, anything else worth surviving a pause) into the state file.
248
+ - **`pause` when a session must end before the elicitation has converged.** Immediately after calling `elicitation-state.sh pause --id <elicitation-id>`, write the scrum-master's own `SessionEnd` handoff (per `templates/SCRUM_BOARD_SCHEMA.md`'s `handoffs/` convention) with `status: "elicitation_paused"` and both `elicitation_id` and `state_file` set — `hooks/on_session_end.sh` routes that into an `elicitation_resume` trigger on `scrum_triggers.jsonl`, which the next scrum-master session's Drain Scrum Triggers Queue procedure picks up (`agents/scrum-master.md`).
249
+ - **On resume**, read `state_file` directly — every converged node, every flagged node, and the checkpoint data (including the confirmed directory-triage lists) are already there. Do not re-run Directory Triage or re-ask about an already-converged node; resume the Convergence Loop only for nodes still `pending` or explicitly deferred.
250
+ - **`complete` when every candidate has converged, been deferred, or been explicitly accepted past the cap.** The state file is left on disk afterward as an audit trail — nothing currently prunes a completed elicitation's state file.
251
+
252
+ ---
253
+
149
254
  ## Modes
150
255
 
151
256
  <!--
@@ -158,7 +263,27 @@ A document whose judgement sections are generic enough to apply to any codebase
158
263
 
159
264
  ### `segment`
160
265
 
161
- Analyse a specific file, directory, or feature that has no board provenance, then give it standard board representation.
266
+ Analyse a specific file, directory, or feature that has no board provenance. Since **E20_S08_T03**, `segment` has two explicit modes — it no longer silently always runs one:
267
+
268
+ | Flag | Mode | What it produces |
269
+ |---|---|---|
270
+ | `--mode delivery` (default when explicit) | Delivery-shaped proposal — today's unchanged flow | A standard epic/story/task proposal, per the Understanding Document |
271
+ | `--mode investigate` | Conversational architecture investigation (new, E20_S08_T03) | Coarse graph nodes/edges plus a `[ARCH]`-tagged board item |
272
+
273
+ **Step 0 — choose a mode.** If `--mode` is given, skip straight to that mode's subsection below. If it is missing, do **not** default silently — present the choice, per the Interaction Pattern in `CLAUDE.md`:
274
+
275
+ ```
276
+ /uncharted segment <target> — which mode?
277
+ 1. Delivery-shaped proposal (produces an epic/story/task to build on this target)
278
+ 2. Conversational architecture investigation (produces graph nodes explaining what this target does)
279
+ 3. Other (describe below)
280
+ ```
281
+
282
+ Silence, a counter-question, or an ambiguous reply is not consent — re-ask. This choice is the entire mechanism by which existing callers keep getting exactly today's behavior (option 1, or `--mode delivery` passed explicitly) while new callers can reach the conversational path deliberately, per the parent story's own acceptance criterion that this split must be explicit, not a silent behavior change.
283
+
284
+ #### Delivery-shaped proposal (`--mode delivery`)
285
+
286
+ Unchanged from before E20_S08_T03 — every step below is exactly what `segment` has always done.
162
287
 
163
288
  **Step 1 — Resolve the target.** Deterministic; do not eyeball it.
164
289
 
@@ -259,6 +384,24 @@ On success, tell the user exactly which files were created, with their IDs.
259
384
 
260
385
  **`/uncharted` writes board files and stops there.** It does not adapt the segment to project conventions, edit or move the code it just analysed, open a worktree, or write an execution plan. That is ordinary developer work, driven by ordinary task files, and it is the developer agent's job — the same as for a task that came from `/brainstorm` or `/pi-plan`. A segment that has reached the board is no longer a special case, and this skill growing its own integration path would be a second, divergent execution route for work the existing one already handles.
261
386
 
387
+ #### Conversational investigation (`--mode investigate`)
388
+
389
+ New in **E20_S08_T03**. Produces a plain-language understanding plus graph nodes for a *specific* target — the same conversational mechanics as `onboard`'s default flow, applied at single-target scale instead of whole-codebase scale. Read **Conversational Elicitation** above (Human-Oracle-Availability Limitation, Directory Triage, Convergence Loop, Multi-Session Persistence) before running this — everything below only sequences those shared mechanics for `segment`'s scope; it does not redefine them.
390
+
391
+ **Step 1 — Resolve the target.** Reuse `resolve-segment-target.sh` exactly as the delivery-shaped path's own Step 1 does above — do not reimplement resolution or the board-linkage check for this mode. A `linked` target is a normal condition here (unlike the delivery-shaped path, an existing epic/story/task referencing the target doesn't disqualify investigating it), but still tell the user before proceeding, the same as the delivery-shaped path does.
392
+
393
+ **Step 2 — Directory triage, only if the target is a directory with subdirectories.** A single-file target has nothing to triage; skip straight to Step 3. For a directory target, run the shared Directory Triage procedure above against the target's immediate subdirectories as the candidate set.
394
+
395
+ **Step 3 — Convergence loop.** Run the shared Convergence Loop procedure above. For a single-file target this is one node; for a directory target (after triage) it is one node per surviving candidate. Initialize persistence first:
396
+
397
+ ```bash
398
+ bash skills/uncharted/scripts/elicitation-state.sh init --id "segment-investigate-$(basename "$RESOLVED_TARGET")-$(date -u +%Y%m%d)" --target "$RESOLVED_TARGET"
399
+ ```
400
+
401
+ **Step 4 — On convergence, write the graph and the board item.** Write each converged node/edge to `project/knowledge-graph/graph.json` per the stub schema (`source: "human"`), then present a single `[ARCH]`-tagged board item proposal — epic, story, or task, whichever level fits what was actually investigated (a single flow is usually task-scale; a whole subsystem may warrant a story or, rarely, an epic) — and stop at the same kind of confirmation gate the delivery-shaped path's Step 6 uses (accept / revise / discard / other). **Nothing is written to `project/board/` before that gate is confirmed**, matching the delivery-shaped path's own "nothing written before option 1" guarantee. On acceptance, write the board item and call `elicitation-state.sh complete`.
402
+
403
+ **This mode never produces a delivery-shaped epic/story/task proposal.** If the investigation surfaces work that should actually be *built* (not just understood), say so as a follow-up recommendation in the `[ARCH]` item's own text and let the user separately invoke `--mode delivery` or `/todo` for that — conversational investigation and delivery planning stay two distinct outputs, per this mode split's own purpose.
404
+
262
405
  ### `import`
263
406
 
264
407
  Pull an external source into the repo, then investigate it as a segment.
@@ -441,28 +584,33 @@ destination.
441
584
 
442
585
  ### `onboard`
443
586
 
444
- Backfill the board for an entire pre-existing codebase at framework-adoption time.
587
+ Give an entire pre-existing codebase board representation at framework-adoption time. Since **E20_S08_T03**, `onboard` has two modes:
445
588
 
446
- > **Placeholder — implemented by E40_S04** (`E40_S04_T01` `provenance` field on epics, `E40_S04_T02` subsystem discovery, `E40_S04_T03` cap enforcement with drop logging, `E40_S04_T04` backfilled epic generation, `E40_S04_T05` `PROJECT_SUMMARY.md` population). All five are live.
447
- >
448
- > Contract this section must honour when filled in:
449
- > - Coarse-first: identifies major subsystems, not individual files. Depth is bounded, not exhaustive.
450
- > - Emits a **capped** number of epics, each marked `provenance: backfilled` so they are distinguishable from normally-authored epics.
451
- > - The cap is explicit and anything dropped to stay under it is reported to the user. No silent truncation.
452
- > - **Board and documentation only.** Never modifies, moves, or restructures the consumer's application code. Jenga lives alongside the app; the app never has to conform to a Jenga convention.
589
+ | Invocation | Mode | Output |
590
+ |---|---|---|
591
+ | `onboard <root>` (default) | Conversational — human-in-the-loop elicitation seeded by the same discovery scripts | `[ARCH]`-tagged board items + coarse graph nodes in `project/knowledge-graph/graph.json` |
592
+ | `onboard <root> --legacy` | Fully-automated, zero-prompt, capped-backfilled-epic pass — E40_S04's original behavior, byte-for-byte unchanged | `provenance: backfilled` epics |
593
+
594
+ **`--legacy` is not a deprecated fallback — it is the designated tool for a codebase with no available human oracle.** Read **Human-Oracle-Availability Limitation** under Conversational Elicitation above before choosing between the two; that section states explicitly when `--legacy` is the *correct* choice, not a lesser one.
595
+
596
+ > **Build status:** the legacy pipeline (`E40_S04_T01`-`T05`: `provenance` field, subsystem discovery, cap enforcement, backfilled epic generation, `PROJECT_SUMMARY.md` population) is complete and unchanged by this rework — see **Legacy mode** below. The conversational default is new as of `E20_S08_T03` — see **Conversational default** below.
453
597
 
454
598
  #### The hard constraint: `onboard` never touches application code
455
599
 
600
+ This holds in **both** modes — conversational and legacy alike.
601
+
456
602
  **`onboard` mode must never modify, move, rename, delete, or restructure any file that belongs to
457
603
  the consumer's application.** This is not a best-effort convention — it is the reason `onboard`
458
604
  exists as a *board-only* mode rather than a generic migration tool. Its entire output surface,
459
605
  without exception, is:
460
606
 
461
- - `project/board/` (the backfilled epic files this section produces)
462
- - `project/rapports/analysis/` (understanding documents and the subsystem cap record)
463
- - `project/PROJECT_SUMMARY.md` (populated by `E40_S04_T05`)
607
+ - `project/board/` (backfilled epics in `--legacy` mode; `[ARCH]`-tagged epics/stories/tasks in conversational mode)
608
+ - `project/rapports/analysis/` (understanding documents and the subsystem cap record — `--legacy` mode only; conversational mode's primary output is the graph, not this document type — see Conversational Elicitation above)
609
+ - `project/PROJECT_SUMMARY.md` (populated by `E40_S04_T05`, `--legacy` mode only)
610
+ - `project/knowledge-graph/graph.json` (coarse graph nodes/edges — conversational mode only, per the stub schema)
611
+ - `project/queue/elicitation-state/` (multi-session persistence scratch state — conversational mode only, git-ignored, not a durable artifact)
464
612
 
465
- Nothing under any other path is ever created, edited, or deleted by `onboard` mode. Jenga's board
613
+ Nothing under any other path is ever created, edited, or deleted by `onboard` mode, in either mode. Jenga's board
466
614
  and skills live *alongside* the application; the application never has to conform to a Jenga
467
615
  convention to be onboarded. This guarantee is enforced in three independent places, not just
468
616
  stated here:
@@ -476,6 +624,34 @@ stated here:
476
624
  3. **A verifiable post-run check** (below): after a full `onboard` run, `git status` in the
477
625
  analysed repository must show changes only under `project/`.
478
626
 
627
+ #### Conversational default
628
+
629
+ New in **E20_S08_T03**. Runs when `onboard` is invoked without `--legacy`.
630
+
631
+ **Step 1 — discovery stays scripted.** Run the exact same deterministic discovery chain the legacy pipeline uses — `discover-subsystems.sh` — unchanged. Evidence-gathering is not where this rework touches anything; only what happens with the output differs.
632
+
633
+ ```bash
634
+ bash skills/uncharted/scripts/discover-subsystems.sh <root>
635
+ ```
636
+
637
+ **Step 2 — directory triage.** Feed the discovery output's candidate paths into the shared Directory Triage procedure (see Conversational Elicitation above), and stop at its confirmation gate before anything else happens.
638
+
639
+ **Step 3 — initialize persistence.**
640
+
641
+ ```bash
642
+ bash skills/uncharted/scripts/elicitation-state.sh init --id "onboard-$(basename "$(cd "$root" && pwd)")-$(date -u +%Y%m%d)" --target "<root>" --cap 5
643
+ ```
644
+
645
+ **Step 4 — convergence loop, once per surviving candidate.** Run the shared Convergence Loop procedure (see Conversational Elicitation above) for each candidate that survived triage — this is where the legacy pipeline's `apply-subsystem-cap.sh` and `write-backfilled-epics.sh` would have silently produced a capped set of `provenance: backfilled` epics; the conversational default asks about each one instead, subject to the same risk-weighted gating and hard turn cap. There is deliberately **no subsystem cap** on the conversational path — the turn cap already bounds cost per candidate, and capping the *candidate count* the way the legacy path does would silently drop subsystems from a human-in-the-loop conversation the same way the legacy path drops them from an unattended one, which defeats the point of asking. A codebase with far more subsystems than is practical to walk through conversationally in one sitting is exactly the multi-session case Multi-Session Persistence exists for — pause, resume across sessions, rather than truncate the candidate list.
646
+
647
+ **Step 5 — on convergence, write the graph and the board item(s).** Per candidate: write the converged node(s)/edge(s) to `project/knowledge-graph/graph.json`, then present an `[ARCH]`-tagged board item proposal at whichever level fits (an individual subsystem is usually story-scale; the whole run may warrant a single `[ARCH]` epic containing one story per converged subsystem — judgement call, not a fixed rule) and stop at a confirmation gate before writing to `project/board/`, exactly as `segment --mode investigate`'s Step 4 does. Call `elicitation-state.sh complete` once every candidate has converged, been deferred, or been resolved past the turn cap.
648
+
649
+ **`PROJECT_SUMMARY.md` population still applies, unchanged in spirit.** Once the conversational pass has produced its `[ARCH]` items, hand off to the scrum-master for the same `PROJECT_SUMMARY.md` Overview/Architecture & Structure drafting-and-confirmation flow described under **Updating PROJECT_SUMMARY.md from onboard evidence** below (Steps A-D) — substituting the conversational pass's converged understanding for the legacy pipeline's `kept` array as the evidence source. Do not skip the stub-vs-real-content check in Step B just because the evidence came from a conversation instead of a script.
650
+
651
+ #### Legacy mode (`--legacy`)
652
+
653
+ Everything below is `E40_S04`'s original, fully-automated, zero-prompt pipeline — **unchanged** by this rework, reachable only via the explicit `--legacy` flag.
654
+
479
655
  #### The subsystem cap
480
656
 
481
657
  Live as of `E40_S04_T03`. `onboard` does **not** create one epic per discovered subsystem — a
@@ -592,7 +768,9 @@ outside `project/` ended up tracked by git.
592
768
 
593
769
  #### Updating PROJECT_SUMMARY.md from onboard evidence
594
770
 
595
- Live as of `E40_S04_T05`. This is the last step of an `onboard` run, after the backfilled epics
771
+ Live as of `E40_S04_T05`, and reused by both `onboard` modes since `E20_S08_T03` — the conversational default's own Step 5 above hands off here too, substituting its converged understanding for the `kept` array as the evidence source described below. Nested under Legacy mode structurally only because it was written before the conversational path existed; treat "Steps A-D" as shared, not legacy-only.
772
+
773
+ This is the last step of an `onboard` run, after the backfilled epics (legacy) or `[ARCH]` items (conversational)
596
774
  above have been written (or confirmed skipped). Its job is to close the gap the epic itself
597
775
  describes: a project adopting Jenga should not end up with a populated board sitting underneath a
598
776
  `PROJECT_SUMMARY.md` that still reads as if the codebase were empty.
@@ -684,10 +862,11 @@ hard constraint** above, since that file was never a required write, only a perm
684
862
  These hold across every mode:
685
863
 
686
864
  - **Read-only against application code**, with one exception: `import` mode writes an acquired source to a location the user has explicitly confirmed. Nothing else in this skill modifies, moves, or restructures a consumer's code.
687
- - **Confirm before writing to the board.** Proposals are presented for approval first, consistent with the brainstorm-before-commit convention.
688
- - **No new rapport type.** Understanding documents use the existing `analysis` type and land in `project/rapports/analysis/`.
689
- - **Never invent findings.** If the evidence does not support a conclusion, say so under Open Questions.
865
+ - **Confirm before writing to the board.** Proposals are presented for approval first, consistent with the brainstorm-before-commit convention. Since `E20_S08_T03`, this also covers Directory Triage's confirmation gate and each converged node's graph/board write in the conversational elicitation flow — same convention, applied to a new output type (graph nodes), not a new exception to it.
866
+ - **No new rapport type.** Understanding documents use the existing `analysis` type and land in `project/rapports/analysis/`. Conversational elicitation's output (graph nodes + `[ARCH]` board items) is not an understanding document and does not need one — see Conversational Elicitation above for what it produces instead.
867
+ - **Never invent findings.** If the evidence does not support a conclusion, say so under Open Questions (delivery-shaped/legacy paths) or state the uncertainty plainly in the node itself (conversational paths — see Human-Oracle-Availability Limitation above).
690
868
  - **Deterministic work belongs in `skills/uncharted/scripts/`**, agent judgement belongs here.
869
+ - **Existing zero-prompt behavior is never silently retired.** `onboard --legacy` and `segment --mode delivery` reproduce exactly what `/uncharted` did before `E20_S08_T03`, with no behavior drift for a caller who keeps using them.
691
870
 
692
871
  ---
693
872
 
@@ -695,8 +874,8 @@ These hold across every mode:
695
874
 
696
875
  `/uncharted` is invocable directly, and is also offered automatically at the two moments it is most needed (E40_S05):
697
876
 
698
- - **`/init`** — when scaffolding detects a non-empty, non-Jenga-scaffolded directory, it offers `onboard` instead of proceeding as though the project were empty.
699
- - **`/reconcile`** — when its normal sync pass finds code with no board linkage, it offers `segment` for the affected paths.
877
+ - **`/init`** — when scaffolding detects a non-empty, non-Jenga-scaffolded directory, it offers `onboard` instead of proceeding as though the project were empty. Since `E20_S08_T03`, this offer surfaces both `onboard` modes — the user picks conversational (default) or `--legacy` at that point, per the mode choice this section describes; `/init` itself makes no decision about which is appropriate.
878
+ - **`/reconcile`** — when its normal sync pass finds code with no board linkage, it offers `segment` for the affected paths. Since `E20_S08_T03`, this offer surfaces both `segment` modes the same way.
700
879
 
701
880
  Both are offers, never automatic execution.
702
881