Problem
Prefix formatting for commit messages, ticket titles, and PR titles is currently hardcoded as {workspace}|{WORK_TYPE}: {title} across multiple skill files. Agents reconstruct the format from prose rules, leading to inconsistencies — conventions leak between contexts, separators get wrong, and the fallback chain (project → global preferences) is frequently skipped.
Context
Change metadata (scope and type) appears in different contexts with different needs:
- Commits: full scope+type prefix (e.g.,
client|feat: )
- Tickets: sometimes type-only, sometimes none (depends on whether the platform supports labels)
- PRs: often none (labels carry the metadata on GitHub)
Three formatting conventions exist in practice:
| Setting |
Both scope + type |
Type only |
scope|type |
client|feat: |
feat: |
type(scope) |
feat(client): |
feat: |
type |
feat: |
feat: |
The current term "workspace" is renamed to "scope" — the standard term from Conventional Commits, and more general than monorepo workspaces.
When scope is known but type is not, no prefix is produced (a bare scope is ambiguous).
Solution
A deterministic bash script (describe-change.sh) replaces all agent-side prefix assembly. Agents call the script with --scope and --type arguments and use the JSON output verbatim. The script reads the active convention from preferences (project → global → ''), formats each context's prefix including the trailing : separator, and returns structured output:
{
"commit_prefix": "client|feat: ",
"ticket_prefix": "feat: ",
"pr_prefix": ""
}
Agents concatenate directly: ${commit_prefix}${title}. No separator decisions.
Preferences schema
commit:
prefix: 'scope|type' # scope|type | type(scope) | type | ''
ticket:
prefix: 'type' # scope|type | type(scope) | type | ''
pr:
prefix: '' # scope|type | type(scope) | type | ''
Resolution chain: .agents/preferences.yaml → ~/.agents/preferences.yaml → ''
Script details
- Standalone bash, installed alongside skills to
{platform_root}/scripts/
- Located at
{skills_root}/../scripts/describe-change.sh — skills reference this relative path
- Hand-rolled YAML parsing scoped to the specific nested keys needed
- Non-empty prefix fields include the trailing
: — the caller does pure concatenation
- Empty prefix fields mean "no prefix" — the caller concatenates with empty string (same result)
Skill changes
_data/commit-format.md: documents all conventions, the script path ({skills_root}/../scripts/describe-change.sh), and the operational instruction to call it
commit/SKILL.md, condense-branch/SKILL.md, orchestrated-coder.md: call script, use commit_prefix
summarize-change/SKILL.md: remove prefix from title entirely; title becomes {ticket_id} {title}
create-ticket/SKILL.md: call script, use ticket_prefix
prepare-pr/SKILL.md: call script, use pr_prefix
- All references:
{workspace} → {scope} in prefix context
Installation
The agents CLI gains a scripts content category in content/scripts/. During install, scripts are copied (or symlinked) to {platform_root}/scripts/.
Acceptance criteria
Problem
Prefix formatting for commit messages, ticket titles, and PR titles is currently hardcoded as
{workspace}|{WORK_TYPE}: {title}across multiple skill files. Agents reconstruct the format from prose rules, leading to inconsistencies — conventions leak between contexts, separators get wrong, and the fallback chain (project → global preferences) is frequently skipped.Context
Change metadata (scope and type) appears in different contexts with different needs:
client|feat:)Three formatting conventions exist in practice:
scope|typeclient|feat:feat:type(scope)feat(client):feat:typefeat:feat:The current term "workspace" is renamed to "scope" — the standard term from Conventional Commits, and more general than monorepo workspaces.
When scope is known but type is not, no prefix is produced (a bare scope is ambiguous).
Solution
A deterministic bash script (
describe-change.sh) replaces all agent-side prefix assembly. Agents call the script with--scopeand--typearguments and use the JSON output verbatim. The script reads the active convention from preferences (project → global →''), formats each context's prefix including the trailing:separator, and returns structured output:{ "commit_prefix": "client|feat: ", "ticket_prefix": "feat: ", "pr_prefix": "" }Agents concatenate directly:
${commit_prefix}${title}. No separator decisions.Preferences schema
Resolution chain:
.agents/preferences.yaml→~/.agents/preferences.yaml→''Script details
{platform_root}/scripts/{skills_root}/../scripts/describe-change.sh— skills reference this relative path:— the caller does pure concatenationSkill changes
_data/commit-format.md: documents all conventions, the script path ({skills_root}/../scripts/describe-change.sh), and the operational instruction to call itcommit/SKILL.md,condense-branch/SKILL.md,orchestrated-coder.md: call script, usecommit_prefixsummarize-change/SKILL.md: remove prefix from title entirely; title becomes{ticket_id} {title}create-ticket/SKILL.md: call script, useticket_prefixprepare-pr/SKILL.md: call script, usepr_prefix{workspace}→{scope}in prefix contextInstallation
The agents CLI gains a
scriptscontent category incontent/scripts/. During install, scripts are copied (or symlinked) to{platform_root}/scripts/.Acceptance criteria
describe-change.shproduces correct JSON for all convention × input combinations:separator; empty prefixes are empty strings''|character in YAML values is handled correctly (quoted strings){workspace}renamed to{scope}in all prefix-related contextscodeassembly-agents installcopies scripts to{platform_root}/scripts/