Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 34 additions & 3 deletions packages/agents/content/skills/_data/artifact-conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ All artifacts live under a configurable base directory (`base_dir`, default `~/a
└── {project-slug}/
├── tickets/
│ └── {ticket-id}/
│ ├── {timestamp}_{slug}_{artifact-type}.md ← ticket-level artifacts
│ ├── {timestamp}_{slug}_{artifact-type}.md ← ticket-level artifacts (devlogs land here when a ticket is in session)
│ └── {run-id}/ ← review run directory
│ ├── {NN}_{role}_{artifact}.md
│ └── ...
├── chats/
│ └── {timestamp}_{descriptive-title}.md
├── devlogs/
│ └── {timestamp}_{concise-title}.md
│ └── {timestamp}_{concise-title}.md ← project-scoped fallback when no ticket is in session
└── plans/
└── {design-documents}.md
```
Expand Down Expand Up @@ -91,6 +91,8 @@ Ticket-level artifacts and run directories both live here. Use `get-session-cont

Non-ticket paths are relative to the project directory. Category names remain configurable via `artifacts.paths.{category}` in preferences.yaml.

Devlogs are dual-homed: when a ticket is in session context they are written as ticket-level artifacts under `tickets/{ticket-id}/`; otherwise they fall back to the project-scoped `devlogs/` path above. Project-scoped fallback devlog filenames retain the legacy `YYYYMMDD-HHMMZ` (no seconds) timestamp prefix for backward compatibility with pre-existing artifacts at that path; ticket-scoped devlogs use the standard `YYYYMMDD-HHMMSSZ` ticket-level shape.

## Naming conventions

### Ticket-level artifacts
Expand Down Expand Up @@ -156,6 +158,35 @@ Plan artifacts include a YAML frontmatter `provenance` block that records author
| `isInteractive` | Present and `true` when the plan was produced through a structured interactive flow. Omitted otherwise. |
| `iteration` | Refinement iteration counter. Absent on first authoring; set to `2` on first refinement, incremented on subsequent refinements. |

## Devlog frontmatter

Devlog artifacts include a YAML frontmatter block that records authoring origin and links the devlog to its ticket, run, branch, and commits. The shape mirrors plan provenance so a single frontmatter parser can serve both artifact types.

```yaml
---
provenance:
skill: create-devlog
timestamp: <ISO 8601 UTC>
baseSha: <short SHA of origin/main> # omit if unresolvable
isInteractive: true
ticket_id: <id> # omit when no ticket is in session
run_id: <run id> # omit when not invoked from an orchestrated wrap-up
branch: <branch name>
commits: [<sha>, ...] # omit for working-tree devlogs
---
```

| Field | Required | Description |
| -------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `provenance.skill` | yes | Always `create-devlog`. |
| `provenance.timestamp` | yes | ISO 8601 UTC timestamp of when the devlog was written. |
| `provenance.baseSha` | no | Short SHA of `origin/main` at write time. Omitted if unresolvable (no remote, shallow clone). |
| `provenance.isInteractive` | yes | Always `true` — devlogs are produced interactively or via an interactive wrap-up. |
| `ticket_id` | no | The ticket ID from session context. Omitted when no ticket is in session (research/exploration sessions). |
| `run_id` | no | The orchestrated run ID. Present only when `/create-devlog` is invoked with `--run-id` (typically by `/wrap-up` for orchestrated runs). |
| `branch` | yes | Current branch name from session context. |
| `commits` | no | List of short SHAs the devlog summarizes. Omitted for `working-tree` invocations; otherwise a single SHA or N SHAs depending on argument. |

## run-index.json

Machine-readable metadata for orchestrated runs. Written and maintained exclusively by the orchestrator. Individual skills do not write to this file directly.
Expand Down Expand Up @@ -551,6 +582,7 @@ The first `coder_change-summary` in a run has no dispositions (nothing to respon
### Ticket-level artifacts

- `change-summary` — Branch change summary for PRs
- `devlog` — Development log entry (falls back to non-ticket path when no ticket is in session)
- `orchestration-plan` — Orchestration plan (`orchestration-plan.json` is a **mutable** artifact overwritten each planning iteration; `{timestamp}_planner_orchestration-plan.md` files are versioned human-readable snapshots)
- `plan` — Implementation plan document
- `plan-review` — Plan review findings (completeness and correctness analysis)
Expand All @@ -561,7 +593,6 @@ The first `coder_change-summary` in a run has no dispositions (nothing to respon

### Non-ticket artifacts

- `devlog` — Development log entry
- `chat-summary` — Conversation summary

## Run lifecycle
Expand Down
66 changes: 59 additions & 7 deletions packages/agents/content/skills/create-devlog/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,25 @@ Summarize changes made in recent commits or the working tree.
- No arguments: Summarize the last commit
- `<n>`: Summarize the last N commits
- `working-tree`: Summarize uncommitted changes
- `--run-id={id}`: Optional. Recorded in frontmatter to link the devlog to a completed orchestrated run. Typically supplied by `/wrap-up`; not used in direct invocations.

## Output format

The devlog file begins with YAML frontmatter (see [Frontmatter](#frontmatter) below) followed by the markdown body:

```markdown
---
provenance:
skill: create-devlog
timestamp: 2026-04-18T15:30:00Z
baseSha: 4f8b158
isInteractive: true
ticket_id: '426'
run_id: 20260419-012539Z
branch: 426
commits: [a1b2c3d, e4f5g6h]
---

# Devlog: {Concise description}

**Date**: {YYYY-MM-DD HH:MM UTC}
Expand Down Expand Up @@ -48,16 +63,53 @@ Summarize changes made in recent commits or the working tree.

## Saving

Resolve artifact directory using `get-session-context` to obtain `artifact_base_dir`, `project_slug`, and `artifact_paths`. The devlogs path is `artifact_paths.devlogs` (default: `devlogs`).
Resolve session context and the artifact directory before writing.

### Path resolution

1. Call `get-session-context` to obtain `ticket_id`, `project_slug`, `artifact_base_dir`, `artifact_paths`, and `branch_name`.
2. If `ticket_id` is non-null: save as a ticket-level artifact at:

```
{artifact_base_dir}/projects/{project_slug}/tickets/{ticket_id}/{filename}
```

Filename uses the ticket-level shape: `{YYYYMMDD-HHMMSSZ}_{slug}_devlog.md`.

3. Else (no ticket — research/exploration sessions): save to the project-scoped fallback at:

Full path: `{artifact_base_dir}/projects/{project_slug}/{devlogs_path}/`
```
{artifact_base_dir}/projects/{project_slug}/{artifact_paths.devlogs}/{filename}
```

Filename uses the existing project-scoped shape: `{YYYYMMDD-HHMMZ}_{concise-title-in-kebab-case}.md`.

4. `mkdir -p` the target directory before writing.

`get-session-context` returns `ticket_id: null` for branches without a recognizable ticket prefix (e.g., `experiment/foo`). Treat null as "no ticket" — never produce a path containing `tickets/null/`.

Follow [artifact conventions](../_data/artifact-conventions.md).

Artifact type: `devlog`. Filename format:
### Frontmatter

```
{YYYYMMDD}-{HHmm}Z_{concise-title-in-kebab-case}.md
```
Prepend YAML frontmatter to every newly created devlog. The shape mirrors `save-plan`'s provenance block so a single parser handles both artifact types. See [Devlog frontmatter](../_data/artifact-conventions.md#devlog-frontmatter) for the full field reference.

Generation rules:

- **`provenance` block** — always emitted.
- `skill`: always `create-devlog`.
- `timestamp`: current UTC time in ISO 8601 format.
- `baseSha`: run `git rev-parse --short origin/main`. Omit the field if the command fails (no remote, shallow clone). Mirrors `save-plan` behavior.
- `isInteractive`: always `true`.
- **`branch`** — always emitted, taken from `branch_name` in session context.
- **`ticket_id`** — emit only if non-null in session context. Omit otherwise.
- **`run_id`** — emit only if `--run-id={id}` was supplied as an argument. Do not perform any filesystem discovery to find a run directory; the caller is the source of truth.
- **`commits`** — derived from the invocation argument:
- No argument (last commit): single short SHA from `git log -n 1 --format=%h`.
- `<n>` (last N commits): list of N short SHAs from `git log -n {N} --format=%h`.
- `working-tree`: omit the `commits` field entirely.

### Filename examples

Example: `20250809-1430Z_fix-csp-violation-preventing-script-injection.md`
- Ticket-scoped: `20260418-153000Z_make-devlogs-ticket-scoped_devlog.md`
- Project-scoped fallback: `20250809-1430Z_fix-csp-violation-preventing-script-injection.md`
4 changes: 3 additions & 1 deletion packages/agents/content/skills/save-artifact/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ Run artifacts are saved by the skills that produce them (`review-change`, `respo
### Ticket-level

- `change-summary` — Branch change summary for PRs
- `devlog` — Development log entry (ticket-scoped when a ticket is in session; falls back to project-scoped `devlogs/` otherwise)
- `orchestration-plan` — Orchestration plan for the orchestrate engine
- `plan` — Implementation plan document
- `plan-review` — Plan review findings (completeness and correctness analysis)
Expand All @@ -72,7 +73,6 @@ Run artifacts are saved by the skills that produce them (`review-change`, `respo

### Non-ticket

- `devlog` — Development log entry
- `chat-summary` — Conversation summary

## Path resolution
Expand All @@ -91,6 +91,8 @@ Create the directory if needed.

Read `artifact_paths` from the `get-session-context` manifest for category paths (chats, devlogs, plans). These are relative to the project directory: `{artifact_base_dir}/projects/{project_slug}/{category}/`.

Devlogs use the `devlogs` category path only as a fallback — when a ticket is in session context they are written as ticket-level artifacts under `tickets/{ticket_id}/` instead. See [artifact conventions](../_data/artifact-conventions.md#non-ticket-paths) for the dual-homing rule, and `create-devlog/SKILL.md` for the devlog frontmatter shape.

Follow [artifact conventions](../_data/artifact-conventions.md).

## Slug generation
Expand Down
16 changes: 9 additions & 7 deletions packages/agents/content/skills/wrap-up/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,17 @@ Gather signals to classify the session and identify actionable items.

Check these signals in order to classify the session:

| Signal | How to check | Session type |
| -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
| Orchestrated run artifacts | Look for `run-index.json` in the artifact directory for the current ticket (resolve via `get-session-context` → ticket ID, then check `{artifact_base_dir}/projects/{project_slug}/tickets/{ticket_id}/`) | **Orchestrated** |
| Code changes on branch | `git diff --name-only {default_branch}...HEAD` produces output | **Interactive dev** |
| Review artifacts in conversation | Conversation contains review findings or `/review-change` output | **Review** |
| None of the above | No code changes, no run artifacts, no review artifacts | **Research/exploration** |
| Signal | How to check | Session type |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
| Orchestrated run artifacts | Look for run subdirectories under the current ticket directory (resolve via `get-session-context` → ticket ID, then list subdirectories of `{artifact_base_dir}/projects/{project_slug}/tickets/{ticket_id}/` that contain `run-index.json`) | **Orchestrated** |
| Code changes on branch | `git diff --name-only {default_branch}...HEAD` produces output | **Interactive dev** |
| Review artifacts in conversation | Conversation contains review findings or `/review-change` output | **Review** |
| None of the above | No code changes, no run artifacts, no review artifacts | **Research/exploration** |

Check from top to bottom. Use the first match. If an orchestrated run also has interactive changes after the run, treat it as orchestrated (the run-summary already captured the orchestrated portion).

When the orchestrated path matches, identify the specific run directory whose basename will be captured as `run_id` for later use. Run directory basenames begin with a `YYYYMMDD-HHMMSSZ` timestamp prefix and therefore sort chronologically; if multiple run directories exist under the ticket (restarts or separate review cycles), pick the one with the lexicographically greatest basename — that is the latest run. Phase 3 passes this `run_id` through to `/create-devlog` as `--run-id`, so the devlog frontmatter can link back to the run that produced the work.

#### 1b. Scan for deferred items

Deferred items are things that were identified during the session but intentionally not addressed.
Expand Down Expand Up @@ -249,7 +251,7 @@ Process confirmed actions in this order:
1. **Tickets for findings** — invoke `/create-ticket` once per ticket (or once for combined items). Use the item description as the ticket body seed. Apply the label from the issue's context (feature, bug, refactoring, dependencies, ci, tests). Classify items using the prefix: `fixme` → bug, `todo` → task, `warning` → bug, `recommendation` → improvement, `suggestion` → improvement.
2. **Tickets for legacy items** — invoke `/create-ticket` once per item. Label as technical debt or the appropriate category.
3. **Post insights to ticket** — post each `ticket comment` insight via `gh issue comment {number} --body "{insight}"` (ticket number from `get-session-context`). If no ticket is available, re-route to devlog.
4. **Save session devlog** — invoke `/create-devlog`. Insights with `devlog` destination are automatically included in the devlog content; no separate action is needed for them.
4. **Save session devlog** — invoke `/create-devlog`. When the session was detected as orchestrated in Phase 1a, pass the captured run ID through as `/create-devlog --run-id={run_id}` so the devlog frontmatter links back to the run. Insights with `devlog` destination are automatically included in the devlog content; no separate action is needed for them.

**Between each action**, briefly report the result (ticket URL, artifact path) before proceeding to the next.

Expand Down
Loading