Skip to content

feat(tools-triage-flow): ticket triage flow — thin workflow + tools-triage skill - #334

Open
sergepr wants to merge 11 commits into
mainfrom
feat/triage-flow-source
Open

feat(tools-triage-flow): ticket triage flow — thin workflow + tools-triage skill#334
sergepr wants to merge 11 commits into
mainfrom
feat/triage-flow-source

Conversation

@sergepr

@sergepr sergepr commented Aug 28, 2026

Copy link
Copy Markdown

Adds tools-triage-flow, a flow that triages one issue-tracker ticket per invocation for GD Tools' AI SDLC pipeline (TSSM ticket triage): it elicits requirements from the ticket through comment round-trips, posts a triage assessment, then creates and links a Story in the target TOOL project. It is delivered as a thin workflow plus one flow-owned skill, tools-triage.

This is the Rosetta-side half of a two-repo flow. The trigger (a Jira webhook / CI dispatch) and the PR publishing live in tools-harness-intake and griddynamics/tools-aisdlc-knowledgebase. Wiring those to actually call /tools-triage-flow and to execute the write artifacts it produces is separate, deliberately out-of-scope follow-up work — see Deferred below.

Why the flow looks the way it does

It has no live connection to the Issue Tracker, by design. The caller composes whatever it knows about the ticket into free text and passes it in; the flow never reads anything itself. Every write it decides to make is composed into a JSON artifact on disk for a later executor to run — it never sends one. Two consequences reviewers should hold onto:

  • No comment ID, created issue key, URL, or link ID exists at compose time. The five state fields that name one are recordable only as the literal "pending — see <artifact path>" sentinel. A plausible-looking identifier anywhere in this flow would be a fabrication, and the next invocation would trust it.
  • Phase 6's create-then-link pair cannot complete in one tick: link_issues needs a real target-project key, which does not exist until someone executes the create artifact and that result reaches a later invocation's input. This is handled as an expected resumable state (create composed, link pending), not a failure.

It is deployment-specific, not a general-purpose Rosetta flow. The target project key TOOL, issue type Story, the TSSM: Tool / TSSM: Project custom fields, and the Grid Dynamics tool-impact reasoning are hardcoded constants for this deployment. There is no config file anywhere in this build.

Architecture: thin workflow + one flow-owned skill

The flow originally shipped as 7 files under workflows/ — a 216-line triage-flow.md plus 6 phase files — which inverted Rosetta's layering. docs/schemas/workflow.md requires the workflow file to stay "small and short, skills already define how things work", yet the workflow carried <intake_contract>, <write_artifact_contract>, <idempotency> and a 42-line <state_and_resumption>. The flow owned no skill at all: deleting the shared jira-write skill earlier in this branch inlined its knowledge into the workflow rather than into a flow-owned skill.

It also polluted the command surface: all 6 phase files were emitted flat into every target's command folder (plugins/core-claude/workflows/, core-cursor/commands/, core-copilot/commands/) and nested under core-codex/.agents/skills/triage-flow/phases/. Their user-invocable: false frontmatter carried through verbatim, but Cursor and Copilot command frontmatter has no such key — so /triage-flow-intake and its five siblings were reachable there as user commands.

Final shape, following the coding-agents-prompting-flow + coding-agents-prompt-authoring pattern already established in this repo:

instructions/r3/core/
  workflows/tools-triage-flow.md    thin orchestration: 6 phase blocks, 149 lines
  skills/tools-triage/
    SKILL.md                        646 lines — role · when_to_use · core_concepts
                                    (cross-stage invariants, stage flow, section map)
                                    · <intake_and_state>  input contract + redaction,
                                      state semantics, change detection, resume routing,
                                      state skeleton
                                    · <elicitation_and_assessment>  one iteration,
                                      completion/routing decision, assessment rubrics,
                                      assessment skeleton
                                    · <writes_and_tool_issue>  compose contract (ops,
                                      NNN, gate, no-identity), the three op JSON shapes,
                                      create-then-link stage
                                    · validation_checklist · pitfalls
    README.md                       44 lines — maintainer doc, never loaded at runtime

3 authored files. Single-file skill: no references/, no assets/. Sections point at each other by tag (`<write_artifacts>` below, `<state_and_idempotency>` above), and each carries its own checklist, pitfalls, and the shape of the file it produces. The trade — recorded in README.md along with the reversal path — is that activating the skill loads all 646 lines, with no partial loading.

The workflow keeps only orchestration: phase sequence, per-phase subagent / role / subagent_required_model / must-be-subagent, state ownership, scope boundary, and a sequencing-and-evidence checklist. It names the skill and the topic per phase and lets the skill route — it does not deep-link into references/, because the closed alias grammar forbids it (SKILL FILE never carries a skill name; skill-folder isolation is grammar-enforced).

Why one skill rather than two or six. A separate write-mechanics skill would recreate the independently-discoverable shared Jira skill that jira-write's deletion was meant to end. Six per-phase skills would burn the shared ~1K-token skill-description budget for a single-caller flow. tools-triage is flow-owned: tools-triage-flow is its only caller, and nothing in it is written for reuse elsewhere.

Why the tools- prefix. triage-flow was a generic name in a shared namespace for a deployment-specific flow, and this repo already uses "triage" for PR/issue triage (.github/workflows/repo-triage.yml). The prefix marks both artifacts as one self-contained unit, stops the skill reading as general-purpose, and leaves triage-flow free for a real generic triage flow. A skill may not take the flow's own name — Codex and Antigravity convert the workflow into a skill of that exact name, so tools-triage (skill) and tools-triage-flow (flow) are deliberately distinct and coexist in those targets.

Input / output

  • Input: { ticket_key, reason?, ticket_details, artifacts_dir? }, supplied directly by the caller. ticket_details is free text with no fixed schema — no file read, no config read, no live fetch. artifacts_dir defaults to agents/TEMP.
  • Output, all under <artifacts_dir>/<TICKET-KEY>/: <TICKET-KEY>-REQUIREMENTS.md, <TICKET-KEY>-TRIAGE-ASSESSMENT.md, <TICKET-KEY>-TRIAGE-FLOW-STATE.md, and one issue-writes/<NNN>-<op>.json per composed write (op ∈ add_comment, create_issue, link_issues). Executing those against the real tracker is a separate, cross-repo step.
  • Idempotency: a SHA-256 hash of this tick's redacted ticket_details versus last_processed_ticket_details_hash. Deliberately coarser than a comment-ID diff — free text carries no comment IDs — so its worst case is an unnecessary elicitation re-run on a no-op text change, never a missed update.

POC-scope overrides — please review these explicitly

Two documented simplifications weaken normal Rosetta gates. Both are flagged in-file with a POC-SCOPE-OVERRIDE: marker naming exactly what they substitute for, and both are prose, not config — removing the paragraph restores the gate.

  1. Compose gate (tt-write-artifacts.md): skips dangerous-actions step 5 and hitl's always-require-approval rule for all three compose operations — unattended at compose time by design, matching the unattended-CI posture. The dangerous-actions content gate itself still runs, once per artifact. The override governs only whether an artifact is written to disk; it says nothing about whether executing it later is safe. create_issue is the one exception it does not cover: because a created issue can never be deleted, that compose must state which duplicate-prevention check ran and what it found, or it is refused.
  2. Completion rule (tt-elicitation-and-completion.md): "Open Questions empty" alone flips the requirement units to Approved, standing in for hitl's explicit affirmative-sentence approval. The flow's human gate lives downstream, in the consumer of its artifacts (harness-intake's PR review), not in Jira ticket state.

sensitive-data redaction is not relaxed: intake redacts ticket_details itself before anything downstream sees it, and evidence is cited by type/count/location only, never the masked value.

Deferred (seams only, do not implement here)

Real cron/webhook trigger · sub-hourly cadence · any risk-based gating on the assessment levels · local eligibility re-checking · service-account credential swap · changes to tools-harness-intake · post-creation management of the created issue · a comment announcing it · executing the composed artifacts and feeding results back. One known residual gap: this flow cannot live-validate custom-field option values or link-type names before composing — that validation belongs to whatever executes the artifacts.

Verification

  • plans/triage-flow-skill-extraction/ carries a 151-row invariant inventory built before any content moved, with every normative rule, constant, rubric level, state field, and regression-preventing negation traced to its new home. Its destination-key table maps each row to the file and section it now lives in.
  • Automated needle checks across every destination file — 108 on the first pass, re-run after the rename and again after the file consolidation, each time with zero misses. One miss on the first pass was fixed and re-verified.
  • Plugins regenerated across all 7 targets, exit 0. Zero stale triage-flow* or ticket-triage* artifacts remain; exactly one tools-triage-flow command and one tools-triage skill per target, one INDEX entry each.
  • data-collection shows zero diff from its pre-branch state; no jira-write references remain anywhere.

Two things recorded honestly rather than smoothed over, both in content-map-verification.md §S6: the workflow deviates from the plan by not deep-linking into the skill (the alias grammar forbids it), and POC-SCOPE-OVERRIDE occurrences dropped 14 → 8 because per-phase restatements of the same compose override were consolidated into the contract of record — both distinct overrides survive with full framing.

Vendor neutrality

The instructions describe an Issue Tracker, not a vendor. Prose mentions of Jira are gone, and the artifact directory is issue-writes/, not jira-writes/. The op names (add_comment, create_issue, link_issues), target_issue_key, and the state-file fields were already neutral. The target constants (TOOL, Story, Action item, TSSM: Tool / TSSM: Project) stay — those are the deployment's real values, not vendor terminology.

One jira string is kept on purpose: a pitfall naming agents/jira-triage.config.json, a config file deleted earlier in this branch. It works precisely because it names the exact file an agent primed on the old design would hunt for.

⚠️ Cross-repo item this PR cannot close: if tools-harness-intake already references jira-writes/, it needs the same rename. The path was safe to change here only because the executor that reads these artifacts does not exist yet.

PR size

44 changed files, of which 30 are generated plugins/** output: npx rosettify-plugins copies every authored file into all 7 agent targets (claude, cursor, cursor-standalone, copilot, copilot-standalone, codex, antigravity), and those outputs are tracked in this repo. The authored surface is 3 files under instructions/r3/core/, plus 8 plan/verification docs and 3 one-line registry entries (docs/definitions/skills.md, workflows.md, agents/IMPLEMENTATION.md).

Worth knowing when reading the commit history: the skill was first authored as 11 files (6 references + 3 assets + SKILL.md + README), consolidated to 5, then inlined to 2. The second and third commits are pure file merges with no behavior change — the needle sweep was re-run after each, always zero misses.

Review guide

Start with content-map-verification.md — each row names a rule and where it lives. Then skills/tools-triage/SKILL.md: it is the entire behavioral surface now. workflows/tools-triage-flow.md is orchestration only. Design history for the earlier decoupling work is in plans/triage-jira-decoupling/HANDOFF.md.

…tool-issue creation

Adds the triage-flow workflow (intake, requirements elicitation via comments,
posted assessment, and linked target-project issue creation on completion),
its jira-write skill (write-capable Jira counterpart to data-collection's
read-only binding), and the supporting MCP/config wiring:

- instructions/r3/core/workflows/triage-flow*.md: orchestrator + 6 phases
  (intake, elicitation, publish-questions, completion-check, assess,
  create-tool-issue)
- instructions/r3/core/skills/jira-write/: write-capable skill (post comment,
  transition, reassign, create issue, link issues), content-level gated via
  dangerous-actions
- agents/jira-triage.config.json + agents/jira-mcp-auth-header.sh: deployment
  config and MCP auth header helper
- .mcp.json: registers the jira-service-account MCP server
- .gitignore: ignore the local (untracked) jira-triage.secrets.json the auth
  helper reads

Source-only: intentionally excludes the plugins/* regeneration and
marketplace/plugin.json version bumps produced by rosettify-plugins for
#332/#333 — that build output is regenerated by CI, not carried in source
PRs. Also excludes the unrelated rosettify-plugins lightweight-profile test
fix that had been bundled into #332.

Supersedes #332 and #333.
@github-actions

Copy link
Copy Markdown
Contributor

Rosetta Triage Review

Summary: Adds triage-flow (a 6-phase, tick-based, resumable ticket-triage workflow: intake → elicitation → completion-check → publish-questions/assess → create-tool-issue) plus jira-write, a new write-capable Issue Tracker skill, and the deployment config/MCP wiring (agents/jira-triage.config.json, agents/jira-mcp-auth-header.sh, .mcp.json) needed to run it against Jira. Source-only PR; plugin regeneration is intentionally excluded (build output, not source).

This touches instructions/r3/**, so it was reviewed as instruction-quality content (per this repo's triage policy) with a dedicated Rosetta prompt-authoring subagent review, cross-checked against docs/schemas/workflow.md, docs/schemas/skill.md, and sibling instruction files.

Findings:

  • jira-write/references/jira-write-vendor-binding.md, triage-flow.md, and triage-flow-intake.md all name data-collection's private reference file issue-vendor-binding.md by filename. Per pa-hardening.md's cross-skill isolation rule, another skill's internal references/ files must never be named directly — only "USE SKILL data-collection to ..." intent phrasing is allowed.
  • All subagent_required_model lists across the 6 new phase files use R2-era model IDs (claude-4.8-opus-high, gpt-5.5-high, gemini-3.1-pro-high, gpt-5.4-low) rather than the current R3 canonical set used consistently elsewhere in instructions/r3 (claude-opus-5, gpt-5.6-sol/terra/luna, gemini-3.7-flash).
  • triage-flow.md's frontmatter description and jira-write/SKILL.md's description both run well past the schema's ~15-token / pa-hardening's <30-token cap (roughly 2x over on the workflow file).
  • jira-write/SKILL.md's <dangerous_actions_gate> claims steps 1–4 of dangerous-actions "still run" while skipping step 5, but dangerous-actions/SKILL.md defines one atomic 5-step process with no documented provision for partial invocation — the "content-level check still applies" claim isn't actually licensed by the skill it's overriding.
  • The POC-SCOPE-OVERRIDE in jira-write disables human confirmation for all 5 write capabilities (comment, transition, reassign, create, link) behind one config flag, but triage-flow itself only ever uses comment/create/link — transition and reassign are explicitly out of scope for this flow. Any future caller of jira-write under the same flag silently inherits unattended transition/reassign, which is broader than this build's own justification supports.
  • jira-write/SKILL.md's body states "never hardcode a specific tool name," then itself says "Jira account" / "a live, shared Jira ticket" twice in <core_concepts> and once in <identity_note> — the vendor-neutral framing leaks into the main skill file instead of staying confined to references/jira-write-vendor-binding.md, unlike the data-collection skill it's modeled on.

Caveats:

  • Design is otherwise coherent: the phased tick model, two-state resumability for the irreversible create-then-link write, and comment-ID-based (not author-based) idempotency are all well-reasoned and clearly documented, with the POC-scope shortcuts flagged inline rather than hidden.
  • .mcp.json, agents/jira-mcp-auth-header.sh, and .gitignore changes were checked; no secrets are committed, and the auth helper correctly reads from an untracked sibling file or JIRA_API_TOKEN.

Suggestions:

  • Reword the data-collection internal-file references to intent-level ("USE SKILL data-collection...") across the three files listed above.
  • Refresh all subagent_required_model lists to the current R3 canonical model IDs.
  • Trim both over-length frontmatter descriptions to fit the schema's token budget.
  • Either scope the POC-SCOPE-OVERRIDE to only the write capabilities this flow actually uses (comment/create/link), or explicitly document in the override note that transition/reassign inherit the same bypass for any future caller.

Questions:

  • Is the plan to scope confirmation_gate_override per-operation in a follow-up, or is a skill-wide bypass the intended long-term shape once this moves past POC?

Automated triage by Rosetta agent

Per the automated Rosetta prompt-authoring review on #334:

- Reword the three direct references to data-collection's internal
  issue-vendor-binding.md file to intent-level phrasing ("USE SKILL
  data-collection..."), per pa-hardening's cross-skill isolation rule
  (no naming another skill's references/ files directly).
- Refresh all 6 phase files' subagent_required_model lists from R2-era
  IDs to the current R3 canonical sets already used by sibling
  workflows: the opus tier matches requirements-authoring-flow.md's own
  requirements-engineer/architect phases; the bounded/executor tier
  matches init-workspace-flow.md's discovery phase.
- Trim triage-flow.md's and jira-write/SKILL.md's frontmatter
  descriptions to fit the schema's token budget (both were ~2x over).
- Document in jira-write's POC-SCOPE-OVERRIDE note that the
  confirmation-gate bypass is skill-wide, not per-operation: transition
  and reassign inherit the same unattended bypass under
  confirmation_gate_override even though this build only exercises
  comment/create/link.

Not addressed here (left for human review, per the same automated
report): the dangerous-actions step-skipping claim's licensing, and the
vendor-neutral-framing leak into jira-write/SKILL.md's core_concepts —
both need a judgment call rather than a mechanical fix.
@sergepr

sergepr commented Aug 28, 2026

Copy link
Copy Markdown
Author

Pushed a follow-up commit (211efec) addressing the automated Rosetta triage review:

  • Reworded the 3 direct issue-vendor-binding.md references to intent-level phrasing (USE SKILL data-collection...), per pa-hardening's cross-skill isolation rule.
  • Refreshed all 6 phase files' subagent_required_model lists from stale R2-era IDs to the current R3 canonical sets (matched to requirements-authoring-flow.md and init-workspace-flow.md's equivalent roles).
  • Trimmed both over-length frontmatter descriptions to schema budget.
  • Documented that jira-write's POC-SCOPE-OVERRIDE is skill-wide, not per-operation — transition/reassign inherit the bypass even though this build only uses comment/create/link.

Left open for review, since they need a judgment call rather than a mechanical fix:

  • Whether the dangerous-actions "steps 1-4 still run" claim is actually licensed by that skill's atomic 5-step process.
  • The vendor-neutral-framing leak into jira-write/SKILL.md's core_concepts (mentions "Jira account" directly instead of staying capability-generic).

…override framing

Per the automated Rosetta triage review on #334 (2 remaining findings not
addressed in 211efec, left for review since they seemed like judgment
calls at the time):

- core_concepts and dangerous_actions_gate said "Jira account" / "Jira
  ticket" despite the file's own stated principle one paragraph earlier
  ("never hardcode a specific tool name"). Reworded both to "Issue
  Tracker", matching data-collection's convention (the skill this file
  is modeled on) and jira-write-vendor-binding.md's own capability-generic
  prose. The skill's name, directory, and file paths stay Jira-specific
  on purpose (this build is a Jira-only POC, consistent with
  jira-triage.config.json / jira-mcp-auth-header.sh / the
  jira-service-account MCP registration) — only the two body-prose
  mentions were the actual inconsistency.
- The POC-SCOPE-OVERRIDE paragraph claimed "the content-level
  blast-radius check (steps 1-4) still runs" as if dangerous-actions
  licenses partial application of its own 5-step process; it doesn't —
  dangerous-actions defines one linear process, and this is (per a repo
  search) the only place in instructions/r3 that overrides its step 5 /
  hitl's "dangerous actions ALWAYS require explicit approval" rule.
  Reworded so the content-level check is framed as this build's own
  choice to keep it, not something dangerous-actions sanctions running
  standalone. The underlying policy question — whether unattended
  writes to a live Jira ticket are acceptable — is unchanged and still
  belongs to human review; this only fixes the wording's claim of
  license it didn't have.

No config keys, frontmatter names, intake_contract shape, or
INVOKE SUBAGENT/APPLY PHASE syntax touched — prose only, same category
as 211efec.
@sergepr

sergepr commented Aug 28, 2026

Copy link
Copy Markdown
Author

Pushed a second follow-up commit (ddf7fad) closing out the remaining 2 findings from the automated Rosetta triage review that 211efec left open for review:

  • core_concepts and dangerous_actions_gate said "Jira account" / "Jira ticket" despite this file's own stated principle one paragraph earlier ("never hardcode a specific tool name"). Reworded both to "Issue Tracker", matching data-collection's convention (the skill this one is modeled on) and jira-write-vendor-binding.md's own capability-generic prose. Note: the skill's name/directory/file paths stay Jira-specific on purpose — this build is a Jira-only POC, consistent with jira-triage.config.json, jira-mcp-auth-header.sh, and the jira-service-account MCP registration. Only the two body-prose mentions were the actual inconsistency.
  • The POC-SCOPE-OVERRIDE paragraph claimed "the content-level blast-radius check (steps 1-4) still runs," implying dangerous-actions licenses partial application of its own 5-step process — it doesn't (it defines one linear process, and this is the only place in instructions/r3 that overrides its step 5 / hitl's "dangerous actions ALWAYS require explicit approval" rule). Reworded so the content-level check is framed as this build's own choice to keep, not something dangerous-actions sanctions running standalone.

On the underlying design question that wording change doesn't resolve — why unattended writes to a live ticket at all: triage-flow's whole mechanism is the comment round-trip — phase 4 posts Open Questions derived from the elicitation phase's Requirements.md, and the requester waits for the ticket reporter's reply in a comment, not an interactive prompt in this session. Gating every one of those on a human confirmation here would defeat the flow's actual design (a tick-based, asynchronous loop meant to run unattended between CI dispatches), not just add friction to it. The bypass is also narrower than it looks: scoped to comment/create/link only (transition/reassign are unused by this build, explicitly out of scope), every write is manually revertible except create issue (which instead carries its own extra duplicate-prevention-evidence requirement before it's allowed to fire), and the actual human-in-the-loop gate for this flow's output sits downstream, in harness-intake's own PR review — not inside Jira ticket state.

All 6 findings from the automated review are now addressed across 211efec + ddf7fad.

@bbiloskursky1
bbiloskursky1 requested a review from omaiesh as a code owner August 31, 2026 12:08
@isolomatov-gd

isolomatov-gd commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Maybe you can intro what and why this flow was implemented?

  1. There is no skill included you mentioned.
  2. Why is it this big? Are we explaining to AI something it already knows?
  3. Did you check if you could just extend https://github.com/griddynamics/rosetta/blob/main/instructions/r3/core/skills/backlog/SKILL.md ?
  4. What was the purpose of {"op": "add_comment", "target_issue_key": "<key>", "payload": {"body": "<composed body>"}, "composed_at": "<ISO8601>"}  and <artifacts_dir>/<TICKET-KEY>/jira-writes/<NNN>-add_comment.json, why can't it show to user for approval and then write directly?
  5. Pls also replace jira and similar tech with technology agnostic keyword issue tracker, etc.
  6. This looks like a regular skill, not the workflow, especially if we talk about triaging a single story.

…skill, rename from triage-flow

The flow shipped as 7 files under workflows/: a 216-line triage-flow.md plus
6 phase files. That inverted Rosetta's layering — docs/schemas/workflow.md
requires the workflow file to stay "small and short, skills already define how
things work", yet triage-flow.md carried <intake_contract>,
<write_artifact_contract>, <idempotency> and a 42-line <state_and_resumption>.
The flow owned no skill at all: deleting the shared jira-write skill earlier
inlined its knowledge into the workflow instead of into a flow-owned skill.

It also polluted the command surface. All 6 phase files were emitted flat into
every target's command folder (plugins/core-claude/workflows/,
core-cursor/commands/, core-copilot/commands/) and nested under
core-codex/.agents/skills/triage-flow/phases/. Their user-invocable: false
frontmatter carried through verbatim, but Cursor and Copilot command frontmatter
has no such key, so /triage-flow-intake and its five siblings were reachable
there as user commands.

Changes:

- New skill instructions/r3/core/skills/tools-triage/ (11 files): SKILL.md
  (role, cross-stage invariants, stage flow, reference router), README.md per
  the <skill_authoring> spec, 6 references/tt-*.md (intake contract ·
  elicitation and completion · write artifacts · assessment rubrics ·
  tool-issue binding · state and idempotency), 3 assets/tt-* (state skeleton,
  assessment skeleton, the three op JSON shapes).
- workflows/tools-triage-flow.md: 216 -> 149 lines. Keeps prerequisites,
  <subagent_policy>, 6 phase blocks with their subagent/role/
  subagent_required_model/must-be-subagent attributes token-for-token,
  <out_of_scope>, and a sequencing-and-evidence checklist. No contract, rubric,
  constant, state shape, or op JSON remains in it.
- The 6 triage-flow-*.md phase files are deleted.
- Renamed from triage-flow to tools-triage-flow, skill named tools-triage. The
  flow is deployment-specific (hardcoded TOOL project, TSSM: custom fields,
  Grid Dynamics tool reasoning) while triage-flow was a generic name in a
  shared namespace, and this repo already uses "triage" for PR/issue triage
  (.github/workflows/repo-triage.yml). The prefix also stops the skill reading
  as a general-purpose shared skill. Cheap now: nothing calls /triage-flow yet.
- Registered tools-triage in docs/definitions/skills.md and tools-triage-flow
  in docs/definitions/workflows.md — the flow was never registered there.
- agents/IMPLEMENTATION.md entry rewritten; plugins regenerated (7 targets).

Behavior-neutral apart from the rename: every rule, rubric, constant,
POC-SCOPE-OVERRIDE marker and state field was relocated, not redefined. The
invocation contract { ticket_key, reason?, ticket_details, artifacts_dir? } and
all runtime artifact names are unchanged.

Verification: plans/triage-flow-skill-extraction/ carries a 151-row invariant
inventory built before anything moved, with each row traced to its new home;
108 automated needle checks across the 11 destination files, re-run after the
rename with zero misses. One deviation and one honest miss are recorded there:
the workflow does not deep-link into the skill (the closed alias grammar
forbids it — SKILL FILE never carries a skill name), and POC-SCOPE-OVERRIDE
occurrences dropped 14 -> 8 because per-phase restatements of the same compose
override were consolidated into the contract of record.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@bbiloskursky1 bbiloskursky1 changed the title feat(triage-flow): add ticket triage workflow, jira-write skill, and tool-issue creation feat(tools-triage-flow): ticket triage flow — thin workflow + tools-triage skill Aug 31, 2026
bbiloskursky-gd and others added 3 commits August 31, 2026 18:43
The PR carried 116 changed files for what is one workflow. 93 of those were
generated plugins/** output — the same authored set copied into 7 agent targets
— but the authored surface was still larger than it needed to be at 12 files,
and runtime-loaded lines had grown 668 -> 779 (+17%) even though the workflow
itself shrank 216 -> 149.

Folded the 3 assets/ files into the reference that owns each and removed the
assets/ folder, then merged the 6 references into 3 by natural grouping. Each
original file became a named section, so nothing lost its identity:

- tt-intake-and-state.md          <intake_contract> · <state_and_idempotency>
                                  · <flow_state_template>
- tt-elicitation-and-assessment.md  <elicitation_and_completion>
                                  · <assessment_rubrics> · <assessment_template>
- tt-writes-and-tool-issue.md     <write_artifacts>
                                  · <write_artifact_templates> · <tool_issue_binding>

Cross-references that pointed at another file now point at a section in the
same file. SKILL.md's routing list went 6 entries -> 3 and its <templates>
section was dropped, since the shapes live inside the references now; README.md's
routing map and invariants updated to match.

Net: authored 12 -> 6 files, skill lines 826 -> 685 (the merge also removed
~140 lines of per-file headers and duplicated pointers), generated plugins/**
93 -> 42 files.

No behavior change: 90 needle checks re-run against the merged destinations with
zero misses, no dangling in-file section pointers, POC-SCOPE-OVERRIDE occurrences
unchanged at 8, plugins regenerated clean across 7 targets with no stale tt-* or
assets/ artifacts left behind.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…thored files)

Chosen after the previous consolidation: take the authored surface down to its
minimum with a skill still in place. The three reference files are now three
stage sections inside SKILL.md, and references/ is gone.

SKILL.md (646 lines): <role> -> <when_to_use_skill> -> <core_concepts> (five
cross-stage invariants, stage flow, section map) -> <intake_and_state> ->
<elicitation_and_assessment> -> <writes_and_tool_issue> -> <validation_checklist>
-> <pitfalls>. Every former file became a named section and every former nested
section kept its own tag, checklist and pitfalls, so nothing lost its identity.

APPLY SKILL FILE pointers became in-file section pointers ("<write_artifacts>
below", "<state_and_idempotency> above"); no SKILL FILE alias remains, since
there are no sub-files to address. README.md rewritten for the single-file shape:
the routing list is a section map, the tt-* filename invariant is replaced by
"section tags are the routing surface", and the load cost is stated plainly.

Authored surface: 3 files — workflows/tools-triage-flow.md (149),
skills/tools-triage/SKILL.md (646), skills/tools-triage/README.md (44,
maintainer doc, never loaded at runtime). Generated plugins/** drops to 21 files.

The trade, recorded in README.md: activating the skill loads all 646 lines, with
no partial loading. The reversal path is written down — split the stage sections
back into references/ and turn the section map into a routing list — if the file
grows much further.

No behavior change: 90 needle checks against the merged destinations with zero
misses, XML tags balanced in the expected top-level order, no dangling in-file
pointers, POC-SCOPE-OVERRIDE occurrences unchanged at 8, plugins regenerated
clean across 7 targets with no stale references/ or assets/ left behind.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…-writes/

Rosetta instructions describe an Issue Tracker, not a vendor. Eleven "Jira"
occurrences remained in the shipped artifacts, in three classes:

- Prose (4), reworded to Issue Tracker: "Jira-shaped intent" in SKILL.md and
  README.md, "reads like a Jira task" in SKILL.md's pitfalls, and phase 4's
  role="Bounded Jira comment publisher" in the workflow. That role attribute is
  one of the phase attributes otherwise held token-for-token (inventory row
  W-39) — changed deliberately here, not by drift.
- The artifact directory (6), renamed jira-writes/ -> issue-writes/ across
  SKILL.md, the workflow, README.md and agents/IMPLEMENTATION.md. Delivered path
  is <artifacts_dir>/<TICKET-KEY>/issue-writes/<NNN>-<op>.json. Cheap now
  because the executor that reads these artifacts is unbuilt, cross-repo work;
  once it exists the path is a contract. Open item that cannot be verified from
  this repo: if tools-harness-intake already references jira-writes/, it needs
  the same rename.
- One kept deliberately (1): the pitfall naming agents/jira-triage.config.json,
  a config file deleted earlier in this branch. A historical identifier, not a
  vendor claim — the warning works because it names the exact file an agent
  primed on the old design would hunt for.

The op names inside the artifacts (add_comment, create_issue, link_issues),
target_issue_key, and the state-file fields were already vendor-neutral. The
target constants (TOOL, Story, Action item, TSSM: Tool / TSSM: Project) stay —
they are the deployment's real values, not vendor terminology.

Plugins regenerated across 7 targets; the only "jira" string left in any
generated copy is the intentional config-file pitfall.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request instructions skills, subagents, rules, workflows, commands for AI agents needs more work

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants