@jenga-ai/agent 1.3.0 → 3.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.
- package/README.md +93 -256
- package/agents/developer.md +9 -8
- package/agents/scrum-master.md +57 -23
- package/agents/tester.md +51 -5
- package/hooks/on_session_end.sh +13 -1
- package/lib/generate-agent-context.js +18 -1
- package/lib/generate-copilot-instructions.js +18 -1
- package/lib/generate-skill-allow-list.js +197 -0
- package/lib/skill-allow-list.json +42 -0
- package/package.json +17 -13
- package/scripts/apply-j-prefix.sh +243 -0
- package/scripts/consume-context-digest.sh +103 -0
- package/scripts/generate-j-alias.sh +333 -0
- package/scripts/postinstall.js +25 -0
- package/scripts/sweep-stale-context-digests.sh +132 -0
- package/scripts/validate-board.sh +5 -0
- package/scripts/write-context-digest.sh +230 -0
- package/skills/{brainstorm → j-brainstorm}/SKILL.md +9 -2
- package/skills/{btw → j-btw}/SKILL.md +9 -2
- package/skills/{clearify → j-clearify}/SKILL.md +9 -2
- package/skills/{close-story → j-close-story}/SKILL.md +92 -13
- package/skills/j-close-story/scripts/check-privatized.sh +345 -0
- package/skills/{close-story → j-close-story}/scripts/check-story-closeable.sh +1 -1
- package/skills/{close-story → j-close-story}/scripts/extract-task-diff-stats.sh +1 -1
- package/skills/{commit → j-commit}/SKILL.md +9 -2
- package/skills/j-continue/SKILL.md +36 -0
- package/skills/{deep-dive → j-deep-dive}/SKILL.md +9 -8
- package/skills/{dev-done → j-dev-done}/SKILL.md +11 -4
- package/skills/{dev-done → j-dev-done}/scripts/classify-commit-outcome.sh +4 -4
- package/skills/{distribute → j-distribute}/SKILL.md +17 -10
- package/skills/{distribute → j-distribute}/scripts/distribute-changes.sh +1 -1
- package/skills/{do → j-do}/SKILL.md +111 -14
- package/skills/j-doc/README.md +155 -0
- package/skills/{doc → j-doc}/SKILL.md +55 -18
- package/skills/j-doc/authoring-notes.md +72 -0
- package/skills/j-doc/scripts/resolve_last_update.py +149 -0
- package/skills/{doc-sync → j-doc-sync}/SKILL.md +9 -2
- package/skills/{dooo → j-dooo}/SKILL.md +9 -2
- package/skills/j-error/SKILL.md +36 -0
- package/skills/{evaluate → j-evaluate}/SKILL.md +9 -2
- package/skills/j-examplify/SKILL.md +49 -0
- package/skills/{help → j-help}/SKILL.md +9 -2
- package/skills/{idea → j-idea}/SKILL.md +10 -3
- package/skills/{idea → j-idea}/assets/idea_handoff_template.md +1 -1
- package/skills/{improve → j-improve}/SKILL.md +9 -2
- package/skills/{init → j-init}/SKILL.md +21 -8
- package/skills/j-init/assets/scope-thresholds_template.json +7 -0
- package/skills/j-jbp/SKILL.md +32 -0
- package/skills/j-lgtm/SKILL.md +28 -0
- package/skills/{pi-plan → j-pi-plan}/SKILL.md +10 -3
- package/skills/{proceed → j-proceed}/SKILL.md +9 -2
- package/skills/{publish → j-publish}/SKILL.md +47 -40
- package/skills/{publish → j-publish}/adapters/droplet.md +1 -1
- package/skills/{publish → j-publish}/adapters/mobile-ios.md +3 -3
- package/skills/{publish → j-publish}/adapters/npm-ci.md +29 -7
- package/skills/{publish → j-publish}/adapters/npm.md +8 -8
- package/skills/{publish → j-publish}/assets/ci-contract.md +2 -2
- package/skills/{publish → j-publish}/schemas/publish.schema.json +1 -1
- package/skills/{publish → j-publish}/scripts/npm_ci_pipeline.sh +21 -1
- package/skills/{publish → j-publish}/scripts/npm_stage_inspect.sh +34 -1
- package/skills/{publish → j-publish}/scripts/npm_stage_pipeline.sh +9 -4
- package/skills/{publish → j-publish}/scripts/publish_deploy.sh +4 -4
- package/skills/{publish → j-publish}/scripts/validate_npm_stage_env.sh +1 -1
- package/skills/{publish → j-publish}/wizards/droplet.md +1 -1
- package/skills/{publish → j-publish}/wizards/mobile-ios.md +1 -1
- package/skills/{publish → j-publish}/wizards/npm-ci.md +1 -1
- package/skills/{publish → j-publish}/wizards/npm.md +1 -1
- package/skills/{reconcile → j-reconcile}/SKILL.md +12 -5
- package/skills/{reconcile → j-reconcile}/scripts/detect-unlinked-code.sh +2 -2
- package/skills/{reconcile → j-reconcile}/scripts/resolve-reconcile-scope.sh +3 -3
- package/skills/{reconcile-origin → j-reconcile-origin}/SKILL.md +13 -6
- package/skills/{redo → j-redo}/SKILL.md +9 -2
- package/skills/{skillify → j-skillify}/SKILL.md +10 -3
- package/skills/{spinoff → j-spinoff}/SKILL.md +9 -2
- package/skills/{status → j-status}/SKILL.md +9 -2
- package/skills/j-todo/SKILL.md +92 -0
- package/skills/{todo → j-todo}/assets/todo_handoff_template.md +1 -1
- package/skills/j-todo/scripts/add_trivial_task.sh +216 -0
- package/skills/j-todo/scripts/update_story_tasks.py +87 -0
- package/skills/{uncharted → j-uncharted}/SKILL.md +35 -28
- package/skills/{uncharted → j-uncharted}/assets/UNDERSTANDING_DOC_TEMPLATE.md +2 -2
- package/skills/{uncharted → j-uncharted}/scripts/detect-dependencies.sh +1 -1
- package/skills/{uncharted → j-uncharted}/scripts/detect-tests.sh +1 -1
- package/skills/{uncharted → j-uncharted}/scripts/directory-triage.sh +3 -3
- package/skills/{uncharted → j-uncharted}/scripts/elicitation-state.sh +3 -3
- package/skills/{uncharted → j-uncharted}/scripts/enumerate-target.sh +1 -1
- package/skills/{uncharted → j-uncharted}/scripts/import-source.sh +1 -1
- package/skills/{uncharted → j-uncharted}/scripts/inspect-provenance.sh +1 -1
- package/skills/{uncharted → j-uncharted}/scripts/resolve-segment-target.sh +5 -5
- package/skills/{uncharted → j-uncharted}/scripts/run-engine.sh +1 -1
- package/skills/{uncharted → j-uncharted}/scripts/validate-proposed-items.sh +2 -2
- package/skills/{uncharted → j-uncharted}/scripts/write-backfilled-epics.sh +1 -1
- package/skills/j-wtf/SKILL.md +27 -0
- package/skills/jenga/SKILL.md +1 -1
- package/skills/jenga/scripts/render-confirmation.sh +55 -18
- package/skills/jenga-permission-level/SKILL.md +1 -1
- package/templates/SCRUM_BOARD_SCHEMA.md +33 -2
- package/templates/agent-context.md.tpl +32 -9
- package/templates/copilot-instructions.md.tpl +66 -11
- package/skills/continue/SKILL.md +0 -29
- package/skills/error/SKILL.md +0 -29
- package/skills/examplify/SKILL.md +0 -42
- package/skills/init/assets/scope-thresholds_template.json +0 -7
- package/skills/jbp/SKILL.md +0 -25
- package/skills/lgtm/SKILL.md +0 -21
- package/skills/todo/SKILL.md +0 -48
- package/skills/wtf/SKILL.md +0 -20
- /package/skills/{close-story → j-close-story}/scripts/compute-scope-divergence.sh +0 -0
- /package/skills/{close-story → j-close-story}/scripts/extract-diff-stats.sh +0 -0
- /package/skills/{close-story → j-close-story}/scripts/update-task-frontmatter.sh +0 -0
- /package/skills/{commit → j-commit}/assets/user_instructions_template.md +0 -0
- /package/skills/{distribute → j-distribute}/CONFIG_SCHEMA.md +0 -0
- /package/skills/{distribute → j-distribute}/scripts/check-version.sh +0 -0
- /package/skills/{distribute → j-distribute}/scripts/commit-version-bump.sh +0 -0
- /package/skills/{do → j-do}/assets/intent-vs-diff-prompt.md +0 -0
- /package/skills/{do → j-do}/assets/sender_template.json +0 -0
- /package/skills/{doc → j-doc}/assets/path-objectives.yaml +0 -0
- /package/skills/{doc-sync → j-doc-sync}/assets/default_excludes.txt +0 -0
- /package/skills/{doc-sync → j-doc-sync}/assets/doc_targets.md +0 -0
- /package/skills/{evaluate → j-evaluate}/assets/evaluation_invokation_template.yml +0 -0
- /package/skills/{evaluate → j-evaluate}/assets/evaluation_rapport_template.md +0 -0
- /package/skills/{idea → j-idea}/assets/idea_template.md +0 -0
- /package/skills/{init → j-init}/assets/.gitignore_template +0 -0
- /package/skills/{init → j-init}/assets/PROJECT_SUMMARY_template.md +0 -0
- /package/skills/{init → j-init}/assets/directory_structure.txt +0 -0
- /package/skills/{init → j-init}/assets/strategy_stub_template.md +0 -0
- /package/skills/{init → j-init}/assets/test-config_template.json +0 -0
- /package/skills/{init → j-init}/assets/workflow_template.json +0 -0
- /package/skills/{init → j-init}/scripts/apply-project-visibility.sh +0 -0
- /package/skills/{init → j-init}/scripts/detect-existing-codebase.sh +0 -0
- /package/skills/{init → j-init}/scripts/init.sh +0 -0
- /package/skills/{pi-plan → j-pi-plan}/assets/epic.json +0 -0
- /package/skills/{pi-plan → j-pi-plan}/assets/story_template.md +0 -0
- /package/skills/{publish → j-publish}/assets/ExportOptions.plist.template +0 -0
- /package/skills/{publish → j-publish}/assets/ownership-matrix.md +0 -0
- /package/skills/{publish → j-publish}/assets/publish.example.json +0 -0
- /package/skills/{publish → j-publish}/assets/publish.example.npm-ci.json +0 -0
- /package/skills/{publish → j-publish}/assets/publish.example.npm.json +0 -0
- /package/skills/{publish → j-publish}/assets/secrets-guide.md +0 -0
- /package/skills/{publish → j-publish}/schemas/fixtures/npm-ci-minimal.json +0 -0
- /package/skills/{publish → j-publish}/schemas/fixtures/npm-ci-with-empty-secrets.json +0 -0
- /package/skills/{publish → j-publish}/schemas/fixtures/npm-ci-with-workflow-path.json +0 -0
- /package/skills/{publish → j-publish}/scripts/check_target_config.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/droplet_pipeline.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/finalize_changelog.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/generate_release_notes.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/ios_pipeline.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/npm_pipeline.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/publish_common.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/reconcile_tags.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/run_gates.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/setup_wizard.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/show_history.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/suggest_semver_bump.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/validate_config.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/validate_droplet_env.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/validate_ios_env.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/validate_npm_ci_env.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/validate_npm_env.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/write_ledger_entry.sh +0 -0
- /package/skills/{reconcile → j-reconcile}/assets/report_format.md +0 -0
- /package/skills/{reconcile-origin → j-reconcile-origin}/scripts/reconcile-origin.sh +0 -0
- /package/skills/{skillify → j-skillify}/assets/init-new/SKILL.md +0 -0
- /package/skills/{skillify → j-skillify}/assets/init-new/assets/.gitignore_template +0 -0
- /package/skills/{skillify → j-skillify}/assets/init-new/assets/PROJECT_SUMMARY_template.md +0 -0
- /package/skills/{skillify → j-skillify}/assets/init-new/assets/directory_structure.txt +0 -0
- /package/skills/{skillify → j-skillify}/assets/init-new/assets/test-config_template.json +0 -0
- /package/skills/{skillify → j-skillify}/assets/init-new/assets/workflow_template.json +0 -0
- /package/skills/{skillify → j-skillify}/assets/init-new/scripts/init.sh +0 -0
- /package/skills/{skillify → j-skillify}/assets/init-old/SKILL.md +0 -0
- /package/skills/{status → j-status}/assets/output_format.md +0 -0
- /package/skills/{todo → j-todo}/assets/todo_template.md +0 -0
- /package/skills/{uncharted → j-uncharted}/assets/SEGMENT_PROPOSAL_TEMPLATE.md +0 -0
- /package/skills/{uncharted → j-uncharted}/scripts/apply-subsystem-cap.sh +0 -0
- /package/skills/{uncharted → j-uncharted}/scripts/discover-subsystems.sh +0 -0
|
@@ -1,21 +1,36 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: do
|
|
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.
|
|
2
|
+
name: j.do
|
|
3
|
+
description: Polyfill alias of the do skill under a collision-safe directory name. Identical behavior to /do — 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. Use when the bare /do form is shadowed by another tool's own built-in command of the same name.
|
|
4
4
|
keywords:
|
|
5
5
|
- do
|
|
6
6
|
- execute
|
|
7
7
|
- implement
|
|
8
8
|
- work on
|
|
9
9
|
- build
|
|
10
|
+
- j-do
|
|
11
|
+
- polyfill
|
|
10
12
|
examples:
|
|
11
13
|
- "implement the login feature"
|
|
12
14
|
- "work on the API endpoint"
|
|
15
|
+
- "j-do"
|
|
13
16
|
metadata:
|
|
14
17
|
prefered_agent: developer
|
|
15
18
|
---
|
|
16
19
|
|
|
17
20
|
# Do — Execute Scrum Board Tasks
|
|
18
21
|
|
|
22
|
+
This skill is a literal-directory-name duplicate of `skills/do/`. It exists so that `/j-do` (and `j.j-do`) give a guaranteed-unshadowed way to reach the same flow as `/do`, even if a host tool's own built-in command of the same name would otherwise shadow or override the bare `/do` alias (Claude Code's native skill resolution is a literal-string, directory-name-based match — see `docs/skill-authoring.md`'s "Invocation Convention").
|
|
23
|
+
|
|
24
|
+
This file is generated/synced by `scripts/generate-j-alias.sh do` from `skills/do/SKILL.md` — do not hand-edit it; re-run the generator instead to pick up source changes.
|
|
25
|
+
|
|
26
|
+
## `--trivial` Flag
|
|
27
|
+
|
|
28
|
+
**Syntax:** `/do <id> --trivial` — a dispatch-time override, distinct from `/todo --trivial` (a creation-time flag documented in `skills/todo/SKILL.md`). Where `/todo --trivial` writes a brand-new task straight to `execution_scope: inline`, `/do <id> --trivial` overrides an **already-existing** task's `execution_scope` — whatever it currently is, including absent (legacy tasks with no execution-scope fields at all) — to `inline` at the moment it's dispatched. See `### 4.1.5. \`--trivial\` Dispatch-Time Override` below for the full mechanics.
|
|
29
|
+
|
|
30
|
+
**No softer fallback tier — hard fallback to the full pipeline instead.** Unlike `light` scope (which sits between `inline` and `task`), `--trivial` always forces `inline` directly, with no intermediate tier to fall back to first. To compensate, a `--trivial`-forced run that fails `scripts/smoke-harness.sh` or shows detected scope creep mid-run automatically re-routes to the full `task` pipeline (worktree + developer + tester) via the same `#### Fallback to Full Task-Scope Pipeline` procedure the `light`-tier fallback uses — see `### 4.2`'s failure-handling branches and the shared Fallback subsection under `### 4.3`.
|
|
31
|
+
|
|
32
|
+
**Human-only, same as `/todo --trivial`.** `--trivial` is invoked by a human typing `/do <id> --trivial` — it is never applied autonomously by `/jenga` or the scrum-master's own breakdown/dispatch passes.
|
|
33
|
+
|
|
19
34
|
## Instructions
|
|
20
35
|
|
|
21
36
|
### 0. Load threshold config
|
|
@@ -166,7 +181,7 @@ After acquiring the epic lock and before writing the bundle manifest, scan all o
|
|
|
166
181
|
|
|
167
182
|
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.
|
|
168
183
|
|
|
169
|
-
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`).
|
|
184
|
+
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`).
|
|
170
185
|
|
|
171
186
|
3. **If `unexpected` is non-empty**:
|
|
172
187
|
a. Write a Markdown conflict report to `project/queue/conflict-<task_id>.md` with the following structure:
|
|
@@ -318,9 +333,40 @@ Before invoking the developer, check whether this task was manually scoped by a
|
|
|
318
333
|
```
|
|
319
334
|
Then proceed to step 4.2.
|
|
320
335
|
|
|
336
|
+
### 4.1.5. `--trivial` Dispatch-Time Override
|
|
337
|
+
|
|
338
|
+
After override validation (step 4.1) and before branching on `execution_scope` in step 4.2, check whether this invocation was `/do <id> --trivial`.
|
|
339
|
+
|
|
340
|
+
1. **Detect the flag.** If the task was invoked as `/do <id>` with no `--trivial` flag, skip this entire section and proceed directly to `### 4.2`.
|
|
341
|
+
|
|
342
|
+
2. **If `--trivial` is present**, read the task's current `execution_scope` from frontmatter. Treat an absent value as `task`, per the epic's backward-compatibility rule (a task that omits `execution_scope` is treated as `execution_scope: task`). Call this the **prior tier** — this covers both tasks nobody flagged as trivial at creation (an already-assigned `story`/`task`/`light` tier) and legacy tasks with no `execution_scope` set at all.
|
|
343
|
+
|
|
344
|
+
3. **Overwrite `execution_scope` to `inline`** in the task's frontmatter, unconditionally — `--trivial` always forces `inline`, never a softer "lightest safe tier."
|
|
345
|
+
|
|
346
|
+
4. **Record the override for audit**, reusing the existing `jenga_assigned` / `override_justification` pairing already defined in `templates/SCRUM_BOARD_SCHEMA.md` for exactly this situation ("scope overridden by a human"), rather than inventing a new field:
|
|
347
|
+
- Set `jenga_assigned: false` (if not already `false`).
|
|
348
|
+
- Set (or append to, if already present) `override_justification`:
|
|
349
|
+
```
|
|
350
|
+
override_justification: "/do --trivial dispatch-time override on <date>: execution_scope forced from '<prior_tier>' to 'inline' by human operator."
|
|
351
|
+
```
|
|
352
|
+
- Also set (or append to) `scope_rationale`, mirroring the phrasing convention `skills/todo/scripts/add_trivial_task.sh` already uses for the creation-time flag, so both audit fields agree on the prior tier:
|
|
353
|
+
```
|
|
354
|
+
scope_rationale: "forced inline via /do --trivial (dispatch-time override); prior execution_scope was '<prior_tier>'"
|
|
355
|
+
```
|
|
356
|
+
- Emit a non-fatal log line (styled like 4.2's `AUTO-CORRECTION` message):
|
|
357
|
+
```
|
|
358
|
+
TRIVIAL OVERRIDE [<task_id>]: execution_scope forced from "<prior_tier>" to "inline" via --trivial dispatch-time override.
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
5. **Set an in-session marker** (this dispatch is a `--trivial`-forced run) — this does not need to be persisted to frontmatter; it only needs to survive for the remainder of this `/do` invocation. This marker is distinct from an organically-assigned `execution_scope: inline` task (one the scrum-master or `/jenga` assigned `inline` to directly, with no `--trivial` involved) because its failure handling differs — see `### 4.2`'s failure-handling steps below. Do not confuse a `--trivial`-forced run with an organic `inline` task when applying those steps.
|
|
362
|
+
|
|
363
|
+
6. **Proceed to `### 4.2. Inline Execution Path`** with `execution_scope` now `inline`. Everything else about inline execution (implementation, smoke test invocation, commit convention) is identical between an organic `inline` task and a `--trivial`-forced one — only the two failure-handling branches in `### 4.2` differ, per the marker set in step 5 above.
|
|
364
|
+
|
|
365
|
+
**Precedence with the locked-task dispatch guard.** If `crucial_level: locked` (checked by `### 4.2`'s locked-task dispatch guard, which always runs and always wins), `--trivial` is redundant but harmless — the task was already going to be forced `inline`. The locked-task guard's own audit fields take precedence for that correction; do not double-write conflicting `override_justification` text. A `locked` task's fallback behavior remains "halt and report," never the `--trivial` fallback below, regardless of whether `--trivial` was also passed.
|
|
366
|
+
|
|
321
367
|
### 4.2. Inline Execution Path (execution_scope: inline)
|
|
322
368
|
|
|
323
|
-
After resolving the task context (step 4)
|
|
369
|
+
After resolving the task context (step 4), passing override validation (step 4.1), and applying the `--trivial` dispatch-time override if present (step 4.1.5), read `execution_scope` from the task frontmatter.
|
|
324
370
|
|
|
325
371
|
**Locked-task dispatch guard (defense-in-depth).** Before branching on `execution_scope` below, read `crucial_level` from the task frontmatter (per `templates/SCRUM_BOARD_SCHEMA.md`'s Crucial Flag Fields). If `crucial_level: locked`:
|
|
326
372
|
|
|
@@ -349,12 +395,14 @@ After resolving the task context (step 4) and passing override validation (step
|
|
|
349
395
|
WARNING [<task_id>]: scripts/smoke-harness.sh not found. Smoke test skipped (stub pass).
|
|
350
396
|
```
|
|
351
397
|
4. **If the smoke test exits non-zero**:
|
|
352
|
-
-
|
|
353
|
-
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
398
|
+
- **If this is a `--trivial`-forced run** (marker set in step 4.1.5 — and `crucial_level` is not `locked`, which never falls back, per 4.1.5's precedence note): do NOT write `status: Failed`. `--trivial` always forces `inline` with no softer "lightest safe tier" to fall back to first, so a smoke-harness failure here goes straight to the shared `#### Fallback to Full Task-Scope Pipeline` procedure below (origin: `trivial`). Do not proceed with the remaining inline steps below — the Fallback procedure takes over from here.
|
|
399
|
+
- **Otherwise** (an organically-assigned `inline` task, `--trivial` not involved): behavior is unchanged from before —
|
|
400
|
+
- Write `status: Failed` to the task's frontmatter.
|
|
401
|
+
- Emit:
|
|
402
|
+
```
|
|
403
|
+
INLINE TASK FAILED [<task_id>]: smoke test returned non-zero exit code. Task marked Failed. Halting.
|
|
404
|
+
```
|
|
405
|
+
- Do not commit. Do not proceed to the next task.
|
|
358
406
|
5. **If the smoke test passes**:
|
|
359
407
|
- Commit the changes using the standard commit convention (`task(<task_id>): <short description>`) via `/commit` in inline mode (E32_S04_T03).
|
|
360
408
|
- Run the **Intent-vs-Diff Check** (see `### 5.1. Intent-vs-Diff Check` below) for this task.
|
|
@@ -365,9 +413,58 @@ After resolving the task context (step 4) and passing override validation (step
|
|
|
365
413
|
7. `inline` tasks always have `needs_docs: false` — skip plan and summary documentation for the implemented task.
|
|
366
414
|
8. Continue to `### 6. Verify documentation`, then `### 7. After successful completion`.
|
|
367
415
|
|
|
368
|
-
If the implementation cannot be completed inline (scope is larger than anticipated
|
|
416
|
+
If the implementation cannot be completed inline (scope is larger than anticipated — detected scope creep mid-run):
|
|
417
|
+
- **If this is a `--trivial`-forced run** (and `crucial_level` is not `locked`): invoke the shared `#### Fallback to Full Task-Scope Pipeline` procedure below (origin: `trivial`) — the same procedure the smoke-harness-failure branch above uses, not a second bespoke re-route.
|
|
418
|
+
- **Otherwise** (an organically-assigned `inline` task): abort and re-route to the normal developer path (step 5), unchanged from before.
|
|
419
|
+
- **Regardless of `--trivial`**, if `crucial_level: locked`, do not re-route via either path above; re-attempt inline or halt and report, per the locked-task dispatch guard above.
|
|
420
|
+
|
|
421
|
+
**If `execution_scope` is `light`** (and `crucial_level` is not `locked` — the locked-task dispatch guard above already ran and takes precedence over any scope check), proceed to `### 4.3. Light Execution Path` below instead of step 5.
|
|
422
|
+
|
|
423
|
+
**If `execution_scope` is not `inline` and not `light`** (or is absent / `task` / `story` / `epic`) **and `crucial_level` is not `locked`**, proceed to step 5 (invoke the developer agent) as normal.
|
|
424
|
+
|
|
425
|
+
### 4.3. Light Execution Path (execution_scope: light)
|
|
426
|
+
|
|
427
|
+
After resolving the task context (step 4), passing override validation (step 4.1), and applying the `--trivial` dispatch-time override if present (step 4.1.5 — note `--trivial` always forces `inline`, so a `light`-scoped task only reaches this section if `--trivial` was *not* passed), if `execution_scope: light` and `crucial_level` is not `locked` (per the locked-task dispatch guard in 4.2, which runs first and always wins), route the task through this path instead of the full `task`-scope pipeline in step 5.
|
|
428
|
+
|
|
429
|
+
`light` sits between `inline` and `task`: unlike `inline`, it spawns a real developer subagent (so it can handle small branching logic that inline's main-session execution isn't suited for); unlike `task`, it does not create a dedicated worktree and does not invoke the tester as a separate step.
|
|
430
|
+
|
|
431
|
+
1. **Spawn a developer 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.
|
|
432
|
+
|
|
433
|
+
2. **After the developer subagent reports implementation complete**, run the smoke test harness using the same invocation convention as `### 4.2. Inline Execution Path`:
|
|
434
|
+
- Run `bash 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.
|
|
435
|
+
- If `scripts/smoke-harness.sh` does not exist, log a warning and treat the result as a pass:
|
|
436
|
+
```
|
|
437
|
+
WARNING [<task_id>]: scripts/smoke-harness.sh not found. Smoke test skipped (stub pass).
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
3. **If the smoke test passes**:
|
|
441
|
+
- The developer subagent self-verifies the implementation against the task's acceptance criteria. No tester subagent is invoked for a `light`-scoped task — this is a deliberate, documented exception to "the tester is the sole status-writer" (`agents/tester.md`), mirroring the same exception already established for `inline` scope in step 5 of `### 4.2`. Since no tester runs, the developer/orchestrator is the one who writes the terminal status for a `light`-scoped task.
|
|
442
|
+
- Commit the changes using the standard commit convention (`task(<task_id>): <short description>`) via `/commit`.
|
|
443
|
+
- Run the **Intent-vs-Diff Check** (see `### 5.1. Intent-vs-Diff Check` below) for this task.
|
|
444
|
+
- Write `status: Passed` and `date_completed: <today>` to the task's frontmatter if self-verification passes.
|
|
445
|
+
- Remove the task from `project/todo.md`.
|
|
446
|
+
- Continue to `### 6. Verify documentation`, then `### 7. After successful completion`.
|
|
447
|
+
|
|
448
|
+
4. **If the smoke test fails (non-zero exit)**: do NOT write `status: Failed` and do NOT halt. Instead, invoke `#### Fallback to Full Task-Scope Pipeline` below (origin: `light`).
|
|
449
|
+
|
|
450
|
+
#### Fallback to Full Task-Scope Pipeline
|
|
369
451
|
|
|
370
|
-
|
|
452
|
+
This is a self-contained, reusable procedure with two current callers — `### 4.2`'s `--trivial`-forced inline failure branches (origin: `trivial`) and `### 4.3`'s `light`-scope smoke-harness failure (origin: `light`) — given a task that was attempted under a reduced-overhead execution scope and failed its smoke-harness check (or, for `trivial`, showed detected scope creep mid-run), do the following. The only thing that varies by caller is the notice text in step 5; steps 1–4 and 6 are identical regardless of origin.
|
|
453
|
+
|
|
454
|
+
1. **Do not mark the task `Failed`.** A smoke-harness failure (or detected scope creep) under a reduced-overhead scope means the scope was too small for the task, not that the task itself is unworkable — the correct response is to retry under full isolation, not to reject the work.
|
|
455
|
+
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.)
|
|
456
|
+
3. **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).
|
|
457
|
+
4. **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.
|
|
458
|
+
5. **Emit a clear, non-fatal fallback notice** to the user/orchestrator, using the message matching the caller's origin:
|
|
459
|
+
- origin `light`:
|
|
460
|
+
```
|
|
461
|
+
LIGHT SCOPE FALLBACK [<task_id>]: smoke test failed; re-routing to full task-scope pipeline (worktree + developer + tester).
|
|
462
|
+
```
|
|
463
|
+
- origin `trivial`:
|
|
464
|
+
```
|
|
465
|
+
TRIVIAL OVERRIDE FALLBACK [<task_id>]: smoke test failed (or scope creep detected); re-routing to full task-scope pipeline (worktree + developer + tester).
|
|
466
|
+
```
|
|
467
|
+
6. Resume normal `task`-scope processing (steps 6–8 below) once the tester returns a verdict.
|
|
371
468
|
|
|
372
469
|
### 5. Invoke the developer agent
|
|
373
470
|
Pass the following to the developer agent:
|
|
@@ -395,7 +492,7 @@ After the developer agent returns (or after inline execution completes), run the
|
|
|
395
492
|
|
|
396
493
|
2. Run `git diff --name-only HEAD~1` to retrieve the list of changed file names (relative paths, one per line).
|
|
397
494
|
|
|
398
|
-
3. Read the prompt template from `skills/do/assets/intent-vs-diff-prompt.md`. Extract the prompt block (the content between the triple backticks under `## Prompt`).
|
|
495
|
+
3. Read the prompt template from `skills/j-do/assets/intent-vs-diff-prompt.md`. Extract the prompt block (the content between the triple backticks under `## Prompt`).
|
|
399
496
|
|
|
400
497
|
4. Substitute the placeholders:
|
|
401
498
|
- `{description}` — full text of the task's `## Description` section
|
|
@@ -417,7 +514,7 @@ After the developer agent returns (or after inline execution completes), run the
|
|
|
417
514
|
|
|
418
515
|
**This check is non-blocking.** It does not change the task's Passed/Failed outcome. It only writes `divergence_flag: true` and emits a warning for human review. Execution continues regardless of the check result.
|
|
419
516
|
|
|
420
|
-
**Prompt calibration:** The prompt in `skills/do/assets/intent-vs-diff-prompt.md` is tuned to flag only files with zero plausible connection to the stated task. Test files, documentation files, lock files, and clearly implied files are excluded from flagging. See the `## False-Positive Tuning Rationale` section in the prompt template for full details.
|
|
517
|
+
**Prompt calibration:** The prompt in `skills/j-do/assets/intent-vs-diff-prompt.md` is tuned to flag only files with zero plausible connection to the stated task. Test files, documentation files, lock files, and clearly implied files are excluded from flagging. See the `## False-Positive Tuning Rationale` section in the prompt template for full details.
|
|
421
518
|
|
|
422
519
|
### 6. Verify documentation
|
|
423
520
|
After the developer completes the task, confirm the following documentation was written:
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# `/doc` Authoring and Usage Guide
|
|
2
|
+
|
|
3
|
+
`/doc` generates or regenerates a complete Markdown document for a resolved target path. The skill owns the entire target file: it resolves the documentation objective first, gathers evidence, reads any existing target for still-valid maintainer intent, then writes a full replacement document.
|
|
4
|
+
|
|
5
|
+
## Basic Usage
|
|
6
|
+
|
|
7
|
+
### Default target
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
/doc
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
When no target is provided, `/doc` resolves the default target from `skills/j-doc/assets/path-objectives.yaml`. Today that default is `README.md`.
|
|
14
|
+
|
|
15
|
+
Expected flow:
|
|
16
|
+
1. Resolve `README.md`
|
|
17
|
+
2. Match the `project overview` objective
|
|
18
|
+
3. Gather project evidence
|
|
19
|
+
4. Regenerate the full `README.md`
|
|
20
|
+
|
|
21
|
+
### Custom target
|
|
22
|
+
|
|
23
|
+
Canonical custom-target form:
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
/doc docs/API.md
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Accepted convenience form:
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
/doc update: docs/API.md
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Both forms resolve `docs/API.md`, then apply the matching rule from `skills/j-doc/assets/path-objectives.yaml`.
|
|
36
|
+
|
|
37
|
+
## Target Resolution and Objective Rules
|
|
38
|
+
|
|
39
|
+
`skills/j-doc/assets/path-objectives.yaml` is the source of truth for:
|
|
40
|
+
- the default target
|
|
41
|
+
- known target paths
|
|
42
|
+
- each path's documentation objective
|
|
43
|
+
- required and optional sections for known targets
|
|
44
|
+
|
|
45
|
+
Known targets bypass ambiguity. Unknown targets must stop for clarification.
|
|
46
|
+
|
|
47
|
+
## Evidence Sources and Precedence
|
|
48
|
+
|
|
49
|
+
`/doc` builds a synthesis context before writing. When sources disagree, use this precedence order:
|
|
50
|
+
1. explicit user instruction
|
|
51
|
+
2. scrum-board context
|
|
52
|
+
3. codebase evidence
|
|
53
|
+
4. git history
|
|
54
|
+
|
|
55
|
+
The synthesis context contract currently includes:
|
|
56
|
+
- `target_path`
|
|
57
|
+
- `objective`
|
|
58
|
+
- `project_name`
|
|
59
|
+
- `project_description`
|
|
60
|
+
- `features`
|
|
61
|
+
- `getting_started`
|
|
62
|
+
- `board_items`
|
|
63
|
+
- `conflicts_resolved`
|
|
64
|
+
- `sources_used`
|
|
65
|
+
- `existing_intent`
|
|
66
|
+
|
|
67
|
+
Use stronger sources to break ties. Do not let weaker evidence overwrite explicit user direction.
|
|
68
|
+
|
|
69
|
+
## `last_update` Provenance
|
|
70
|
+
|
|
71
|
+
`last_update` is the documentation provenance field described by Epic E24's provenance work. It is intended to capture the most recent completed board item that materially updated the target document.
|
|
72
|
+
|
|
73
|
+
### Expected source of truth
|
|
74
|
+
|
|
75
|
+
The provenance lookup relies on scrum-board `docs: [...]` annotations that point at repo-relative documentation targets such as:
|
|
76
|
+
- `README.md`
|
|
77
|
+
- `docs/API.md`
|
|
78
|
+
|
|
79
|
+
Board authors should add `docs` annotations to stories or tasks whenever implementation work changes a specific document or should be reflected in that document later.
|
|
80
|
+
|
|
81
|
+
### How provenance is expected to resolve
|
|
82
|
+
|
|
83
|
+
1. Look for completed board items whose `docs` list includes the target path exactly.
|
|
84
|
+
2. Prefer the most recent qualifying item.
|
|
85
|
+
3. Use that item as the basis for the document's `last_update` value.
|
|
86
|
+
|
|
87
|
+
### Fallback behavior
|
|
88
|
+
|
|
89
|
+
If provenance cannot be resolved, `/doc` should follow the fallback defined by E24_S05:
|
|
90
|
+
- omit `last_update`, or
|
|
91
|
+
- mark it as `unknown`
|
|
92
|
+
|
|
93
|
+
Typical failure modes:
|
|
94
|
+
- the relevant board item never declared `docs: [...]`
|
|
95
|
+
- the target path in the board item does not exactly match the generated path
|
|
96
|
+
- the board item exists but is not yet in a completed/passed state
|
|
97
|
+
|
|
98
|
+
## Ambiguity Gate
|
|
99
|
+
|
|
100
|
+
If the resolved target path is not present in `skills/j-doc/assets/path-objectives.yaml`, `/doc` must not guess.
|
|
101
|
+
|
|
102
|
+
It should stop and ask exactly:
|
|
103
|
+
|
|
104
|
+
```text
|
|
105
|
+
What should <target_path> document? Please describe the objective.
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Example
|
|
109
|
+
|
|
110
|
+
```text
|
|
111
|
+
/doc update: docs/UNKNOWN.md
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Expected behavior:
|
|
115
|
+
- do not generate a file yet
|
|
116
|
+
- do not invent a target objective
|
|
117
|
+
- ask the user what `docs/UNKNOWN.md` is meant to document
|
|
118
|
+
|
|
119
|
+
Once the user clarifies the objective, surface the resolved contract and continue.
|
|
120
|
+
|
|
121
|
+
## Target-Specific Notes
|
|
122
|
+
|
|
123
|
+
### `README.md`
|
|
124
|
+
Use `/doc` with no arguments when you want to regenerate the project overview. The generated file should center on:
|
|
125
|
+
- project description
|
|
126
|
+
- getting started steps
|
|
127
|
+
- examples only when they are strongly supported by evidence
|
|
128
|
+
|
|
129
|
+
### `docs/API.md`
|
|
130
|
+
Use `/doc docs/API.md` (or `/doc update: docs/API.md`) when you want an API reference document. The generated file should remain grounded in known interfaces, endpoints, parameters, return values, and errors.
|
|
131
|
+
|
|
132
|
+
## Tips for Board Authors
|
|
133
|
+
|
|
134
|
+
Add `docs` annotations when board work affects documentation scope or provenance. Good examples:
|
|
135
|
+
|
|
136
|
+
```yaml
|
|
137
|
+
docs:
|
|
138
|
+
- README.md
|
|
139
|
+
- docs/API.md
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Use annotations when:
|
|
143
|
+
- a task introduces or changes user-visible behavior that belongs in README
|
|
144
|
+
- a story adds or changes an endpoint, command, interface, or workflow doc
|
|
145
|
+
- you want `/doc` provenance to trace the work back to the board reliably
|
|
146
|
+
|
|
147
|
+
Avoid annotations when the work has no documentation impact.
|
|
148
|
+
|
|
149
|
+
## Maintainer Checklist
|
|
150
|
+
|
|
151
|
+
Before relying on `/doc`, confirm that:
|
|
152
|
+
1. the target path exists in `skills/j-doc/assets/path-objectives.yaml`, or you are prepared to answer the ambiguity prompt
|
|
153
|
+
2. relevant board items include accurate `docs: [...]` annotations
|
|
154
|
+
3. higher-priority evidence sources are up to date
|
|
155
|
+
4. any existing target file content that should survive regeneration is genuinely still valid
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: doc
|
|
3
|
-
description: Generate or update a documentation file by resolving a target path to a clear documentation objective before writing.
|
|
2
|
+
name: j.doc
|
|
3
|
+
description: Polyfill alias of the doc skill under a collision-safe directory name. Identical behavior to /doc — Generate or update a documentation file by resolving a target path to a clear documentation objective before writing. Use when the bare /doc form is shadowed by another tool's own built-in command of the same name.
|
|
4
4
|
metadata:
|
|
5
5
|
prefered_agent: developer
|
|
6
6
|
keywords:
|
|
@@ -9,15 +9,23 @@ keywords:
|
|
|
9
9
|
- write docs
|
|
10
10
|
- generate docs
|
|
11
11
|
- update docs
|
|
12
|
+
- j-doc
|
|
13
|
+
- polyfill
|
|
12
14
|
examples:
|
|
13
15
|
- "/doc"
|
|
14
16
|
- "/doc docs/API.md"
|
|
17
|
+
- "/doc update: docs/API.md"
|
|
15
18
|
- "generate documentation for the CLI"
|
|
16
19
|
- "update the contributing guide"
|
|
20
|
+
- "j-doc"
|
|
17
21
|
---
|
|
18
22
|
|
|
19
23
|
# Doc — Documentation Synthesis and Regeneration
|
|
20
24
|
|
|
25
|
+
This skill is a literal-directory-name duplicate of `skills/doc/`. It exists so that `/j-doc` (and `j.j-doc`) give a guaranteed-unshadowed way to reach the same flow as `/doc`, even if a host tool's own built-in command of the same name would otherwise shadow or override the bare `/doc` alias (Claude Code's native skill resolution is a literal-string, directory-name-based match — see `docs/skill-authoring.md`'s "Invocation Convention").
|
|
26
|
+
|
|
27
|
+
This file is generated/synced by `scripts/generate-j-alias.sh doc` from `skills/doc/SKILL.md` — do not hand-edit it; re-run the generator instead to pick up source changes.
|
|
28
|
+
|
|
21
29
|
## Input Format
|
|
22
30
|
|
|
23
31
|
```text
|
|
@@ -25,12 +33,15 @@ examples:
|
|
|
25
33
|
```
|
|
26
34
|
|
|
27
35
|
- If `target-path` is omitted, default to `README.md`.
|
|
36
|
+
- If the remainder starts with `update:`, strip that prefix, then trim again before resolving the target path.
|
|
28
37
|
- If `target-path` is provided, use it exactly as written after `/doc`.
|
|
29
38
|
- Do not guess additional arguments or rewrite the requested path.
|
|
30
39
|
|
|
31
40
|
## Reference Asset
|
|
32
41
|
|
|
33
|
-
Load `skills/doc/assets/path-objectives.yaml` before resolving the documentation objective. Treat it as the source of truth for the `default_target`, known target paths, and their structural requirements.
|
|
42
|
+
Load `skills/j-doc/assets/path-objectives.yaml` before resolving the documentation objective. Treat it as the source of truth for the `default_target`, known target paths, and their structural requirements.
|
|
43
|
+
|
|
44
|
+
For extended usage guidance, provenance notes, and board-author tips, see `skills/j-doc/README.md`.
|
|
34
45
|
|
|
35
46
|
## Synthesis Context Contract
|
|
36
47
|
|
|
@@ -47,6 +58,7 @@ board_items: []
|
|
|
47
58
|
conflicts_resolved: []
|
|
48
59
|
sources_used: []
|
|
49
60
|
existing_intent: null
|
|
61
|
+
last_update: null
|
|
50
62
|
```
|
|
51
63
|
|
|
52
64
|
Required fields from E24_S03:
|
|
@@ -60,27 +72,30 @@ Required fields from E24_S03:
|
|
|
60
72
|
- `conflicts_resolved`
|
|
61
73
|
- `sources_used`
|
|
62
74
|
- `existing_intent`
|
|
75
|
+
- `last_update`
|
|
63
76
|
|
|
64
|
-
If the shared collector from E24_S03 is not yet merged, construct a temporary context with the same field names so later steps remain compatible.
|
|
77
|
+
If the shared collector from E24_S03 is not yet merged, construct a temporary context with the same field names so later steps remain compatible. `last_update` is resolved during the provenance step below.
|
|
65
78
|
|
|
66
79
|
## Instructions
|
|
67
80
|
|
|
68
81
|
### 1. Parse the target path
|
|
69
82
|
|
|
70
|
-
1. Read `default_target` from `skills/doc/assets/path-objectives.yaml`. If it is missing, fall back to `README.md`.
|
|
83
|
+
1. Read `default_target` from `skills/j-doc/assets/path-objectives.yaml`. If it is missing, fall back to `README.md`.
|
|
71
84
|
2. Remove the `/doc` command token from the invocation.
|
|
72
85
|
3. Trim the remaining text.
|
|
73
|
-
4. If
|
|
74
|
-
5.
|
|
86
|
+
4. If the trimmed remainder starts with the exact prefix `update:`, remove that prefix and trim the remainder again.
|
|
87
|
+
5. If nothing remains, set `target_path` to `default_target`.
|
|
88
|
+
6. Otherwise, set `target_path` to the trimmed remainder.
|
|
75
89
|
|
|
76
90
|
Examples:
|
|
77
91
|
- `/doc` → `target_path = README.md`
|
|
78
92
|
- `/doc docs/API.md` → `target_path = docs/API.md`
|
|
93
|
+
- `/doc update: docs/API.md` → `target_path = docs/API.md`
|
|
79
94
|
- `/doc docs/CLI.md` → `target_path = docs/CLI.md`
|
|
80
95
|
|
|
81
96
|
### 2. Resolve the objective from the rule table
|
|
82
97
|
|
|
83
|
-
1. Read `skills/doc/assets/path-objectives.yaml`.
|
|
98
|
+
1. Read `skills/j-doc/assets/path-objectives.yaml`.
|
|
84
99
|
2. Find an entry whose `path` exactly matches `target_path`.
|
|
85
100
|
3. If a match exists, set:
|
|
86
101
|
- `objective` to the entry's `objective`
|
|
@@ -105,7 +120,7 @@ If the matched rule includes section guidance, carry it forward as constraints f
|
|
|
105
120
|
|
|
106
121
|
### 4. Ambiguity gate for unknown targets
|
|
107
122
|
|
|
108
|
-
If `target_path` is not present in `skills/doc/assets/path-objectives.yaml`:
|
|
123
|
+
If `target_path` is not present in `skills/j-doc/assets/path-objectives.yaml`:
|
|
109
124
|
|
|
110
125
|
- Ask the user exactly: `What should <target_path> document? Please describe the objective.`
|
|
111
126
|
- Do **not** guess the objective.
|
|
@@ -135,15 +150,37 @@ If `target_path` is not present in `skills/doc/assets/path-objectives.yaml`:
|
|
|
135
150
|
|
|
136
151
|
If the target file does not exist, keep `existing_intent = null`.
|
|
137
152
|
|
|
138
|
-
### 7.
|
|
153
|
+
### 7. Resolve `last_update` provenance before writing
|
|
154
|
+
|
|
155
|
+
1. Run `python3 skills/j-doc/scripts/resolve_last_update.py <target_path>` from the repository root.
|
|
156
|
+
2. The resolver must scan `project/board/epics/`, `project/board/stories/`, and `project/board/tasks/`.
|
|
157
|
+
3. Treat a board item as provenance only when all of the following are true:
|
|
158
|
+
- `status` is exactly `Done` or `Passed`
|
|
159
|
+
- `docs` is a YAML list that contains `target_path` as an exact repo-relative string match
|
|
160
|
+
- `date_completed` is present and parses as `YYYY-MM-DD`
|
|
161
|
+
4. If multiple board items match, select the most recent `date_completed` and store it in `synthesis_context.last_update`.
|
|
162
|
+
5. If no matching provenance is found, set `synthesis_context.last_update = "unknown"`. This is the required fallback because it keeps the frontmatter shape stable while making the missing provenance explicit.
|
|
163
|
+
6. Ignore board items in any other status, items missing `docs`, and items whose `docs` entry uses a non-matching path form.
|
|
164
|
+
|
|
165
|
+
### 8. Generate a complete replacement file
|
|
139
166
|
|
|
140
167
|
1. Build a **full file string** from the synthesis context and the resolved target objective.
|
|
141
|
-
2.
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
168
|
+
2. Start the file with YAML frontmatter for provenance, even when provenance could not be resolved:
|
|
169
|
+
|
|
170
|
+
```yaml
|
|
171
|
+
---
|
|
172
|
+
last_update: <YYYY-MM-DD or unknown>
|
|
173
|
+
---
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
3. Use the resolved `synthesis_context.last_update` value in that frontmatter. Emit `unknown` verbatim when no completed board item provides provenance.
|
|
177
|
+
4. This fallback is mandatory: do not omit the `last_update` key when provenance is missing.
|
|
178
|
+
5. Treat the generated output as the entire authoritative file.
|
|
179
|
+
6. Do **not** patch a single section, append new text to the end, or leave untouched legacy sections in place.
|
|
180
|
+
7. Keep the output valid Markdown.
|
|
181
|
+
8. When writing, replace the old file contents in one operation.
|
|
145
182
|
|
|
146
|
-
###
|
|
183
|
+
### 9. Generate `README.md` for the project-overview objective
|
|
147
184
|
|
|
148
185
|
When `target_path = README.md`, generate the full document around the resolved project-overview contract.
|
|
149
186
|
|
|
@@ -175,7 +212,7 @@ When `target_path = README.md`, generate the full document around the resolved p
|
|
|
175
212
|
- Preserve useful setup warnings from `existing_intent` when they are still valid.
|
|
176
213
|
- Output valid Markdown lists or numbered steps.
|
|
177
214
|
|
|
178
|
-
###
|
|
215
|
+
### 10. Conditionally include a README Examples section
|
|
179
216
|
|
|
180
217
|
Only add `## Examples` to `README.md` when the synthesis context supports a grounded project-type inference.
|
|
181
218
|
|
|
@@ -212,7 +249,7 @@ Choose the strongest evidenced type in this priority order when multiple types a
|
|
|
212
249
|
- Do **not** include placeholder examples, pseudo-commands, or guessed endpoints.
|
|
213
250
|
- If you cannot produce two grounded examples, omit the section instead of improvising.
|
|
214
251
|
|
|
215
|
-
###
|
|
252
|
+
### 11. Generate non-README targets from the rule table
|
|
216
253
|
|
|
217
254
|
For every known non-README target, the path-to-objective rule table determines the file structure. Generate a full document that satisfies the matched rule.
|
|
218
255
|
|
|
@@ -309,6 +346,6 @@ Rules:
|
|
|
309
346
|
- Summarize each entry from commit subjects and, when needed, nearby commit context.
|
|
310
347
|
- Keep newest entries first.
|
|
311
348
|
|
|
312
|
-
###
|
|
349
|
+
### 12. Continue using the resolved objective
|
|
313
350
|
|
|
314
351
|
After the target path and objective are resolved, use them as the contract for all subsequent `/doc` work. Known paths must bypass the ambiguity gate, and all later decisions about evidence gathering, scope, regeneration, and structure must honor the surfaced `target_path` and `objective` instead of inferring a different goal.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# `/doc` authoring notes
|
|
2
|
+
|
|
3
|
+
## `last_update` provenance
|
|
4
|
+
|
|
5
|
+
`/doc` writes a `last_update` frontmatter field at the top of generated documentation files. That value is derived from completed scrum-board items that explicitly declare they affected the target document.
|
|
6
|
+
|
|
7
|
+
The resolver is `skills/j-doc/scripts/resolve_last_update.py`. It scans:
|
|
8
|
+
|
|
9
|
+
- `project/board/epics/`
|
|
10
|
+
- `project/board/stories/`
|
|
11
|
+
- `project/board/tasks/`
|
|
12
|
+
|
|
13
|
+
A board item counts as provenance only when all of the following are true:
|
|
14
|
+
|
|
15
|
+
1. `status` is `Done` or `Passed`
|
|
16
|
+
2. `docs` is a YAML list
|
|
17
|
+
3. The `docs` list contains the target file path as an exact repo-relative match (for example `README.md` or `docs/API.md`)
|
|
18
|
+
4. `date_completed` exists and parses as `YYYY-MM-DD`
|
|
19
|
+
|
|
20
|
+
If multiple board items match, `/doc` uses the most recent `date_completed` as `last_update`.
|
|
21
|
+
|
|
22
|
+
## Required board annotations
|
|
23
|
+
|
|
24
|
+
For provenance to work, the scrum-board item that changed a documentation file must carry a matching `docs: [...]` annotation in its YAML frontmatter.
|
|
25
|
+
|
|
26
|
+
Examples:
|
|
27
|
+
|
|
28
|
+
```yaml
|
|
29
|
+
docs:
|
|
30
|
+
- README.md
|
|
31
|
+
- docs/API.md
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Use repo-relative paths only. The resolver does not normalize absolute paths or `./`-prefixed variants.
|
|
35
|
+
|
|
36
|
+
## Fallback behavior
|
|
37
|
+
|
|
38
|
+
When `/doc` cannot determine provenance, it still emits valid YAML frontmatter and sets:
|
|
39
|
+
|
|
40
|
+
```yaml
|
|
41
|
+
last_update: unknown
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
This fallback is intentional. It keeps the frontmatter shape stable while making the missing provenance explicit to both humans and downstream tooling.
|
|
45
|
+
|
|
46
|
+
## Failure modes and assumptions
|
|
47
|
+
|
|
48
|
+
### Board item completed without `docs` annotations
|
|
49
|
+
|
|
50
|
+
If a task, story, or epic reached `Done`/`Passed` but omitted the target file from `docs`, `/doc` cannot attribute that item to the document. The resolver will ignore it and may fall back to `unknown`.
|
|
51
|
+
|
|
52
|
+
### Target path mismatch
|
|
53
|
+
|
|
54
|
+
Matching is exact and repo-relative. These examples do **not** match `README.md`:
|
|
55
|
+
|
|
56
|
+
- `/Users/sam/.../README.md`
|
|
57
|
+
- `./README.md`
|
|
58
|
+
- `docs/../README.md`
|
|
59
|
+
|
|
60
|
+
Authors should record the canonical repo-relative path that `/doc` was invoked with.
|
|
61
|
+
|
|
62
|
+
### Item not in a completed status
|
|
63
|
+
|
|
64
|
+
Items in statuses such as `Pending`, `In Progress`, `Blocked`, or `Failed` do not count as provenance even if they include the right `docs` annotation. Only completed work is eligible.
|
|
65
|
+
|
|
66
|
+
### Missing or invalid `date_completed`
|
|
67
|
+
|
|
68
|
+
A matching board item without a valid `date_completed` cannot contribute a `last_update` value. The resolver skips it and logs a warning to stderr.
|
|
69
|
+
|
|
70
|
+
### Malformed legacy board files
|
|
71
|
+
|
|
72
|
+
Some older board artifacts may not follow the current YAML-frontmatter schema. The resolver skips unparseable files instead of failing the whole `/doc` run. This is a degradation path, not successful provenance.
|