git:20260926.7fd36d2 to git:20261006.fe13693

3 added, 3 removed. Audit A to A.

---
name: Transitrix Feedback
description: Author an upstream methodology-directed finding as a gated, anonymised entry in the repo's own operations/feedback.md register — the input door to the upstream feedback channel method/06-team-operations.md §3.2 specifies but ships no workflow for. Routes non-methodology observations away first, runs an interview, composes and shows the scrubbed wording for confirmation before writing, allocates the next FB-NNNN, and (on request only) renders a ready-to-send message for hello@transitrix.com without ever transmitting it itself.
when_to_use: User says "log this as feedback for the methodology", "this is a gap in the notation, write it up", "raise a finding upstream", "update FB-0002 to triaged", "what feedback have we filed", or an agent operating under FINDINGS.md's propose → route → scrub protocol resolves an incidental finding's routing to escalate-methodology and needs to write the resulting entry.
min_version: "2.1.0"
allowed-tools: Read, Write, Edit, Bash, Glob, Grep
---
# Transitrix Feedback Skill
Turns "the methodology can't express X" (or "the tooling made Y harder than it should
be") into a scrubbed, committed entry in the repo's own `operations/feedback/feedback.md`
register (or the legacy single-file `operations/feedback.md` if that's what the repo carries) — without
the user hand-writing the front-matter-free block, allocating the `FB-NNNN` id, or
remembering the anonymisation discipline themselves. This is the **entry point** to
the upstream feedback channel
[`method/06-team-operations.md`](../../../method/06-team-operations.md) §3.2
specifies but ships no workflow for.
This directory is the **`feedback` skill** within the `transitrix` plugin (the plugin
root is [`transitrix/`](../../), which carries the shared
[`.claude-plugin/plugin.json`](../../.claude-plugin/plugin.json) manifest, one
`skills/<name>/` directory per skill). Invoked as `/transitrix:feedback`. Written for
any coding agent that can read/write files and run shell commands, not only Claude
Code — same portability discipline as the `adr` skill
([`transitrix/skills/adr`](../adr/)) — check its structure before changing this one.
Mechanism this skill sequences (read before or during first use):
[`method/06-team-operations.md`](../../../method/06-team-operations.md) §3.2 (the
Feedback Record shape, its `id`/`type`/`status`/`upstream` fields) and the repo's own
`FINDINGS.md` (the propose → route → scrub protocol this skill is the tail end of).
This `SKILL.md` does not restate the mechanism — it sequences it.
---
## The three invariants this skill enforces
1. **Route first — a data or model problem is never written here.** A problem with
the modelled enterprise (wrong owner, stale relation, canon disagreeing with its
source) is an `ASSESSMENT` in canon or a `WI`, never a Feedback Record
(`method/06-team-operations.md` §1's hard distinction). This skill rejects that shape and says where
it belongs instead of writing it. See Step 1.
2. **Scrub gate — mandatory, before writing, every time.** This skill composes the
anonymised wording itself and shows the **exact text** it is about to write for
confirmation. It refuses to write an entry carrying a canonical-grammar element ID,
a `canon/`/`field/` path, or organisation-identifying detail — this is a hard
refusal, not a suggestion the user can wave through. See Step 3.
3. **No network, ever, from this skill.** Writing an entry is a local commit to the
adopter's own repo (Step 5, PR — same as `adr`). Exporting an entry (Step 7) only
renders text for the user to paste into an email themselves — it never sends,
never opens an issue or PR on any other repo, and never calls a network endpoint.
The worst this skill can do unattended is leave a `proposed`-shaped local entry
sitting in a PR.
---
## Step 0 — Locate (or scaffold) `operations/feedback/feedback.md`
The register is a directory with a journal file and optional attachment subfolders (`method/06-team-operations.md` §3.2).
**Detect which layout the repo carries:**
1. **New layout (v5.0.0+)** — `operations/feedback/` directory with `operations/feedback/feedback.md` inside:
- Use it as-is. The journal carries all entries; attachment folders live at `operations/feedback/YYYYMMDD/` (one dated folder per attached finding).
2. **Old layout (pre-v5.0.0)** — single file at `operations/feedback.md`:
- The file is still valid and must be preserved. If this is the only register, continue using it; the old layout is still supported.
- **Never migrate automatically**. If the repo has the old layout and you are asked to author an entry, check whether someone is simultaneously trying to create the new layout — if both exist or are being created at once, it's an error (see "Migration hazard" below).
3. **Missing both** — a repo onboarded before the Feedback Record convention shipped, or one that hand-rolled its `operations/` folder, may not have either yet. Scaffold the **new layout** now:
- Create `operations/feedback/` directory (if it does not exist).
- Write `operations/feedback/feedback.md` with exactly this shape:
```markdown
# Feedback register
Methodology-directed findings raised from this repo — see
[`method/06-team-operations.md`](https://github.com/transitrix/methodology/blob/main/method/06-team-operations.md)
§3.2. Sending an entry on to the project is opt-in and manual — see this repo's
`CONTRIBUTING.md` (or `hello@transitrix.com` directly).
## Register
```
No entries yet — the first `FB-0001` is added the first time a finding is actually
raised (Step 4), not at scaffold time.
**Migration hazard — refuse if both exist:**
- If `operations/feedback.md` (old) and `operations/feedback/feedback.md` (new) both exist, this is a migration conflict. Do **not** write to either; report the issue and ask the user to resolve it (choose one layout, delete the other).
- **Never** create a second parallel file (`FEEDBACK.md`, `docs/feedback.md`, `operations/feedback.md` when the new layout exists) — the register is either a single file or a directory containing one journal file, never both (`method/06-team-operations.md` §3.2: "not one-file-per-record like ADR/WI").
---
## Step 1 — Route: is this actually a methodology-directed finding?
Ask what was observed, then classify before doing anything else:
- **A problem with the modelled enterprise or its data** ("this capability's owner
looks wrong", "canon disagrees with the source doc", "we should model this
differently given our own data") → **not** feedback. This is an `ASSESSMENT` written
into canon, or a `WI` if it's a piece of work to queue. Tell the user which, and
stop — do not write a Feedback Record for it (`method/06-team-operations.md` §1; `FINDINGS.md` §2's
`apply` / `escalate-owner` routes).
- **A limitation in the notation, schema, tooling, or documentation itself** — the
methodology cannot express something needed, a skill/validator/CLI command made the
task harder than it should have been, a spec is silent or wrong, or canon is valid
but the methodology could guide adopters toward a better shape → **is** feedback.
Continue to Step 2.
If genuinely ambiguous, ask the user directly rather than guessing — writing a data
problem into the anonymised register loses the very model detail (element IDs, the
organisation's own judgement about ownership) that an `ASSESSMENT` or `WI` needs to
keep, and the scrub gate (Step 3) would refuse to carry that detail anyway.
---
## Step 2 — Interview
Extract, conversationally, in this order:
1. **Observation** — what was seen, in plain language.
2. **`methodology_version`** — read `transitrix.yaml`'s pinned version in this repo;
confirm with the user if it looks stale. **Required** — a finding is always raised
against a specific version (`method/06-team-operations.md` §3.2).
3. **`type`** — one of `notation-gap` | `tooling-friction` | `doc-gap` |
`model-suggestion` (`method/06-team-operations.md` §3.2). If the user isn't sure which, ask what kind
of limitation it was — "couldn't model something" (`notation-gap`), "the skill/CLI
made this harder than it should be" (`tooling-friction`), "the docs didn't say" or
said something wrong (`doc-gap`), "this works but could be guided better"
(`model-suggestion`).
4. **`raised_by`** — the adopter's own role that raised the finding. Any role the
adopter's model admits is valid. If this skill is invoked as the tail end of
`FINDINGS.md`'s protocol from one of the four shipped guides (`Ingest`, `Modeler`,
`Analyst`, `Validator`), use that role name; if invoked standalone, ask the user directly.
5. **`proposed`** (optional) — what the team believes the fix would be.
State your understanding back before composing the entry — the scrub gate in Step 3
is a hard gate on the *wording*, not on whether you understood the observation
correctly.
---
## Step 3 — Scrub gate (mandatory, every time)
1. Compose the anonymised `observation` (and `proposed`, if given) yourself: a
*generic limitation only* — strip every adopter specific. Same discipline
`FINDINGS.md` §2 step 3 already states, applied at the moment of writing.
2. **Show the user the exact text** you are about to write — the full entry block,
verbatim, not a paraphrase — and ask for confirmation before proceeding.
3. **Refuse to write** (state why, then return to Step 2 to rephrase) if the composed
text contains any of:
- a token matching the canonical ID grammar, `<TYPE>-[<middle>-]<INTEGER>`
- (`notations/IDS_AND_REFERENCES.md` §1) — e.g. `GOAL-RETENTION-12`,
- `CAPABILITY-ORDER_FULFIL-3` — this is an element ID, not a generic description;
+ (`notations/IDS_AND_REFERENCES.md` §1, with the capability V/H form in §2) — e.g. `GOAL-RETENTION-12`,
+ `CAPABILITY-V3` — this is an element ID, not a generic description;
- a path under `canon/`, `field/`, or `codex/`;
- an organisation name, a real person's name, or any other organisation-identifying
detail (the same real-names / "publish pattern, not client instance" rule applied
elsewhere in the methodology).
4. This is a hard refusal, not a warning the user can override — if the observation
cannot be stated without one of the above, ask the user to rephrase it more
generically. Loop until the text is clean or the user abandons the entry.
- **Worked negative example** — an observation stated as *"our `CAPABILITY-ORDER_FULFIL-3`
+ **Worked negative example** — an observation stated as *"our `CAPABILITY-V3`
element has no relation kind to link it to `GOAL-RETENTION-12` at Acme Corp"* is
refused on all three grounds (two element IDs, one organisation name) and rewritten,
with the user, as *"no relation kind connects a CAPABILITY element to a GOAL
element"* — which passes.
---
## Step 4 — Allocate `FB-NNNN`, write the entry
**Determine the journal location** (Step 0 has detected which layout):
- **New layout**: `operations/feedback/feedback.md`
- **Old layout**: `operations/feedback.md`
1. Read the journal file from whichever location exists; find every `FB-NNNN` already present (checklist
lines and/or `###` headings) and take the highest `NNNN`. The next id is that
value + 1, zero-padded to four digits — `FB-0001` if the register is still empty.
2. Append **one checklist line** at the bottom of the `## Register` section:
```markdown
- [ ] FB-0003 — <short summary, plain language, ≤ ~12 words> — open
```
Leave the checkbox unchecked — it only becomes `[x]` when `status` reaches
`closed` or `wont-fix` (`method/06-team-operations.md` §3.2).
3. Append **one detail block** below the register, in append order (oldest first,
matching the checklist order):
```markdown
---
### FB-0003
type: notation-gap
methodology_version: "7.0.0"
raised_by: Modeler
date: "2026-07-28"
status: open
upstream: not-sent
observation: <the scrubbed text confirmed in Step 3>
proposed: <optional — omit the line entirely if none was given>
```
`date` is today; `status` starts `open`; `upstream` starts `not-sent` — this skill
never writes an entry pre-marked `sent-upstream` or `answered`, since neither has
happened yet by definition of a freshly-authored entry.
4. Never renumber or reuse an id, even if an earlier entry was later marked
`wont-fix` or `closed` — the sequence is monotonic within the file (`method/06-team-operations.md` §5).
---
## Step 5 — Update status on a later invocation
Triggered by "update FB-0002 to triaged", "mark FB-0001 sent-upstream", "FB-0004 got
an answer", or similar, instead of a fresh observation:
1. **Detect the journal location** (Step 0, same as Step 4): new layout at `operations/feedback/feedback.md` or old layout at `operations/feedback.md`.
2. Locate the `### FB-NNNN` block and its matching checklist line in the journal.
3. Update `status:` to the new value (`open` → `triaged` → `resolved-locally` /
`sent-upstream` → `answered` → `closed` / `wont-fix`, per `method/06-team-operations.md` §3.2 — these
are not required to be strictly linear; `triaged` may resolve straight to
`resolved-locally` or `wont-fix` without ever going upstream).
4. If the status change is about actually sending the entry, also update `upstream:`
to `sent <date>` (or `answered <date>` once a reply arrives) — a distinct field
from `status`, per `method/06-team-operations.md` §3.2. This skill never sets `upstream:` on its own;
only when the user reports they actually sent (or received a reply to) the entry.
5. Update the checklist line's trailing status text to match, and flip its checkbox
to `[x]` only when the new `status` is `closed` or `wont-fix` — every other status
keeps the checkbox open.
6. Never edit `observation`, `proposed`, `type`, `methodology_version`, or the id
itself on a status-update invocation — those are fixed at authoring time; only
`status` and `upstream` (and the checklist line's mirrored text) change later.
---
## Step 6 — Land the change: PR, not merge
1. Branch: `feedback/FB-NNNN` (or `feedback/update-FB-NNNN` for a Step 5 status-only
change).
2. Commit only the journal file change — either `operations/feedback.md` (old layout) or `operations/feedback/feedback.md` (new layout) — depending on which Step 0 detected. On Step 0's first-ever scaffold of the **new layout**, the commit includes directory creation + journal write, called out explicitly rather than buried silently in the same diff.
3. Open a PR. **Never merge it** — same discipline as every other skill in this
plugin; a human accepts the change to their own repo's operations state.
4. The journal file carries no CI gate (`method/06-team-operations.md` §4–§5: outside the ID
grammar, outside `scripts/check-notations.mjs`) — there is no validator script to
run before committing, unlike the `adr` skill's `check-adl.mjs` step. Correctness
here rests entirely on Steps 3–4 of this skill.
---
## Step 7 — Export on request only
Only when the user explicitly asks to send an entry upstream (never automatically,
never as part of Steps 4–6):
1. Render the entry's `type`, `methodology_version`, `observation`, and `proposed`
(if present) as **plain text**, addressed to `hello@transitrix.com` — a
ready-to-send message, not a partial fragment the user has to reassemble.
2. State plainly that **sending it is the team's call** — this skill hands over text,
it does not act on it.
3. Do **not**: send an email, call any network endpoint, open a PR or an issue on
`transitrix/methodology` or any other repo, or otherwise transmit the entry
anywhere. If the user then reports they sent it, that is a separate Step 5
invocation to set `upstream: sent <date>` — this step never sets that field
itself.
4. A grep of this skill's own instructions (and any script it would run) finds no
`curl`, no SMTP call, no `gh issue create` / `gh pr create` aimed at any repo other
than the adopter's own (Step 6), and no `WebFetch`/HTTP call that transmits
content outward — export is text-out, nothing more.
---
## What this skill does NOT do
- Does **not** write a data problem or an enterprise-model finding as a Feedback
Record — Step 1 routes those to `ASSESSMENT` / `WI` instead.
- Does **not** skip or soften the scrub gate — an entry carrying an element ID, a
canon path, or organisation-identifying detail is refused, not flagged as a
warning the user can override (Step 3).
- Does **not** send, transmit, or push an entry anywhere on its own, at any step —
export (Step 7) only renders text; the human sends it, if they choose to at all.
- Does **not** invent a second feedback location — the journal is either a single file
(`operations/feedback.md`) or a directory-based journal (`operations/feedback/feedback.md`),
never both, per `method/06-team-operations.md` §3.2. If both layouts exist (migration conflict),
Step 0 refuses and asks the user to resolve it.
- Does **not** automatically migrate between layouts — Step 0 detects which exists
and uses it; migration must be manual (a git mv command in the user's workflow).
- Does **not** renumber or reuse an `FB-NNNN` id, and does not edit an entry's
`observation`/`proposed`/`type`/`methodology_version` after authoring — only
`status`/`upstream` change on a later invocation (Step 5).
- Does **not** merge its own PR.