Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
159 changes: 159 additions & 0 deletions specs/GH347/product.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# Issue #347: Support configurable template formats for Oz responses

## Product Spec

### Summary

Repositories using Oz workflows should be able to customize deterministic Oz-authored workflow comment text through `.github/oz/config.yml`, using YAML multi-line string templates keyed by workflow and response surface. This should build directly on the shared workflow config introduced in #338, preserve current behavior when no templates are configured, and let maintainers change wording without forking the Python workflow code.

### Problem

Oz workflow comments are still assembled from hardcoded strings spread across shared helpers and workflow entrypoints. That works for this repository, but it forces OSS adopters to edit Python if they want to adjust wording, branding, or repository-specific instructions in Oz-authored comments. It also means small response-copy changes require code changes rather than a reviewed config update in source control.

Issue #338 already established `.github/oz/config.yml` as the reviewable workflow config path. Response templating should extend that existing format rather than introducing another config file or reusing unrelated triage config.

### Goals

- Let repositories configure workflow-owned Oz response templates in `.github/oz/config.yml`.
- Store templates as YAML multi-line strings so full markdown fragments can be reviewed in pull requests.
- Reuse the existing consumer-repo-first config lookup model introduced by #338.
- Keep today’s comment behavior unchanged when the template section is absent.
- Support partial overrides so a repository can customize one or two templates without copying the full default set.
- Expose a stable, documented set of template keys and placeholder variables.
- Fail fast when configured templates are invalid instead of silently posting broken comments.

### Non-goals

- Templating arbitrary model-authored prose such as triage analyses, PR review summaries, or inline analytical replies.
- Adding loops, conditionals, or a general-purpose templating language.
- Introducing a second workflow config file or cross-file merging.
- Changing workflow decisions, labels, assignee behavior, or PR/review state transitions.
- Retrofitting localization, theme packs, or per-run environment-variable overrides for comment copy.

### Figma / design references

Figma: none provided. This is a workflow-config and comment-rendering feature.

### User experience

#### Config location and structure

Response templates live in `.github/oz/config.yml`, the same versioned file introduced for shared workflow settings in #338. The existing lookup order remains unchanged:

1. `.github/oz/config.yml` in the consuming repository
2. `.github/oz/config.yml` in the bundled `oz-for-oss` checkout

Only the first discovered file is used. The workflow does not merge consumer and bundled config files.

Within that file, response templates live under a dedicated top-level section. The initial shape should be:

```yaml path=null start=null
version: 1
self_improvement:
base_branch: auto
workflow_comments:
shared:
powered_by_suffix: |
Comment thread
oz-for-oss[bot] marked this conversation as resolved.
Outdated
_Powered by [Oz](https://oz.warp.dev)_
create-spec-from-issue:
start_new: |
I'm drafting product and tech specs for this issue.
complete_created: |
I created a new [spec PR](${pr_url}) for this issue.
```

`workflow_comments` is optional. If it is absent, Oz keeps using its built-in default copy.

#### Supported surfaces in the first release

The first release should cover workflow-owned, deterministic response text that Oz constructs in Python before posting to GitHub. That includes:

- progress-comment start, session-link, completion, and error copy for the core workflows
- helper-generated sections such as `Next steps`, spec-preview text, and the shared suffix appended to Oz-managed comments
- the triage wrapper text around agent-produced findings, follow-up questions, duplicate lists, maintainer-details framing, and the triage disclaimer
- one-off workflow-owned notices that are still hardcoded directly in entrypoint scripts, such as the unready-assignment message and PR-enforcement close comment

This first release should not template the freeform prose generated by the model itself. For example, these remain model-authored outputs rather than config-authored templates:

- `triage_result.json.summary`
- `triage_result.json.issue_body`
- `triage_result.json.statements`
- `triage_result.json.follow_up_questions`
- `issue_response.json.analysis_comment`
- `review.json.summary` and inline review comments

Those model-authored payloads may still be inserted into configured templates through placeholders, but their underlying text is not managed in `.github/oz/config.yml`.
Comment thread
oz-for-oss[bot] marked this conversation as resolved.

#### Template behavior

Each supported response surface has:

- a stable template key
- a documented set of named placeholders
- a built-in default template that matches current behavior

A repository may override any subset of keys. Missing keys fall back to the built-in default template for that surface.

Template behavior rules:

- Templates are markdown strings and may span multiple lines.
- Templates use named placeholders with `${name}` syntax.
- Only documented placeholders are allowed for a given template key.
- Template rendering happens only when Oz is about to post or update a workflow-owned comment.
- Changing `.github/oz/config.yml` affects future workflow runs only; existing comments are not retroactively rewritten.
- The HTML metadata marker that Oz uses to find/update its own comments remains workflow-owned and is not configurable.
- Template strings must be non-empty. Omitting a template key is the supported way to keep the default behavior.

Representative placeholder examples include:

- `${pr_url}` for created or updated PR links
- `${session_link_markdown}` for the formatted Warp session/conversation link
- `${reporter_mention}` for a preformatted `@user` mention when available
- `${questions_markdown}` or `${duplicate_list_markdown}` for dynamic markdown blocks already assembled by the workflow
- `${required_label}` or `${change_kind}` for enforcement messages

#### Validation and failure behavior

Configured templates should be validated before Oz posts any user-visible comment. Invalid config should fail the workflow with an error that points at `.github/oz/config.yml` and the offending template key.

Validation should catch:

- unsupported template keys
- wrong value types, such as non-string entries
- unknown placeholder names
- missing required placeholder values for a rendered template
- malformed placeholder syntax
- empty template strings

A partially configured file should still work when the configured entries are valid: unconfigured template keys keep their built-in defaults.

#### Documentation

README documentation should explain:

- where response templates live in `.github/oz/config.yml`
- that the config file itself still follows the consumer-first, bundled-fallback lookup order from #338
- the `workflow_comments` section and key naming scheme
- the `${name}` placeholder syntax with concrete examples
- which response surfaces are supported in the first release and which are intentionally out of scope

### Success criteria

- A repository can customize at least one Oz-authored workflow comment surface by editing `.github/oz/config.yml` without modifying Python code.
- A repository can override only a small subset of templates and keep built-in defaults for the rest.
- Repositories with no `workflow_comments` section see no change in posted comments.
- Invalid configured templates fail fast with actionable errors instead of silently posting malformed comments.
- The first supported surface set covers the current hardcoded workflow-owned comment copy across shared helpers and the remaining one-off workflow scripts identified for this issue.
- README documentation is specific enough that a maintainer can successfully customize response text without reading the implementation.

### Validation

- Unit tests cover config parsing, template lookup, placeholder validation, partial overrides, and default fallback behavior.
- Unit tests cover representative rendered comments for progress-comment flows, triage comment wrappers, and one-off workflow notices.
- Regression tests confirm that existing default comment bodies remain unchanged when no template overrides are present.
- Manual verification in a fixture repository confirms that a YAML block-scalar override in `.github/oz/config.yml` changes the next Oz workflow comment on that surface.
- Manual verification confirms that an invalid placeholder name or template key fails the workflow before any user-visible comment is posted.

### Open questions

None for the first release. Model-authored prose remains intentionally out of scope unless a later issue expands this config surface.
Loading
Loading