Files
zielivia 7c81ffe68d feat: pre-intake skills, Definition of Ready, and QA gate hardening (#107)
* feat(sdlc): Definition of Ready gate, Discovery row, and the document's own scope

The generated SDLC.md started at a ticket with "enough detail to act on",
which nothing checked. It now carries a Discovery row driven by om-brainstorm
(#59), a before-intake paragraph naming the spec skills, an after-merge
paragraph saying where the collection stops, and a two-tier Definition of
Ready: ticket-level items only a human can supply, spec-level items a covering
spec provides.

om-auto-manage-issues records READY_STATUS and posts one idempotent not-ready
comment naming the missing items. om-auto-fix-issue's feature route stops with
NOT_READY on a ticket that fails the ticket-level tier instead of speccing
around the gap; a spec-level gap still authors the spec. om-prepare-issue files
tickets with the matching sections. Upgrade note and decision entry included.

* feat(om-discover): product-level discovery and define, with a product-brief.md the other skills read

New interactive skill with three modes (existing product, client idea, own
idea). It runs a context gate over the research directory before writing
anything: a brief section with no interviews, data, or documents behind it
becomes a collection plan with capture templates, never prose. Interview
rounds ask the whole frontier at once with a recommended answer and the
evidence tier it would carry; a skeptic subagent and a quality gate catch
invented personas, unsourced numbers, and benchmarks without a link and date.

The brief tags every claim (interview, data, document, product, benchmark,
synthetic, assumption), carries a coverage line, and gives business rules,
non-goals, and decisions stable ids with an owner, a status, and a required
path to change them. om-brainstorm, om-spec-writing, and om-prepare-issue read
the brief when it exists. Roster, README, docs card, PM role, upgrade note,
and decision entry included.

* feat(om-synthetic-users): personas, simulated interviews, and persona walkthroughs tagged synthetic

New interactive skill. Builds personas from the material the repository
already holds (product-brief.md, a spec, interview notes, data), with stable
ids and every line tagged with its source and no demographics. Runs simulated
interviews that ask about the past, never the future, and walks a named flow
through the personas' eyes: on the brief or spec as a narrative, on a static
prototype through the browser provider, or on the running app booted through
om-prepare-test-env.

Three stances default from the brief's mode: validate on a real product,
simulate with every answer marked to confirm, adversary where agreement is
discarded. Every finding is [SYNTHETIC], paired with the real-user check
that would settle it, and never satisfies the Definition of Ready.
om-ux-review-pr walks as the personas when personas.md exists, om-spec-writing
reads walkthrough reports as hypotheses, om-discover --refresh pulls them into
the brief. Roster, README, docs card, role docs, upgrade note, and decision
entry included.

* feat(review): product-brief non-goals, rules, and decisions as a protected contract

When om-discover has written product-brief.md, its Non-goals, Business
rules, and Decisions (stable ids, owner, status, review-by date, required
path to change) are enforced the way BACKWARD_COMPATIBILITY.md surfaces are.
om-code-review gains a product-decision gate: a change that contradicts an
active entry without a superseding row in the same diff is a blocker quoting
the id; a touched entry past its review-by date is a minor finding.
om-ux-review-pr applies the same to screens.

The decisions in play are surfaced where people work: om-auto-manage-issues
ends its implementation notes with them, om-spec-writing carries a Decisions
in play section and may not default against them, and the unified PR body
template (three synced copies) gains Decisions touched. om-discover --refresh
records human-confirmed assumptions from spec PRs as decisions. SDLC.md and
its template describe the contract; upgrade note and decision entry included.

* feat(om-ux-style): a declared design contract from scratch, in the files the UX skills already read

New interactive skill for repositories with no design system yet. Gathers a
moodboard from references the team chooses (never invented), derives five
confirmed principles and five anti-patterns, defines tokens by role for both
themes with contrast checked, and lists the components the product's flows
need with all six states plus three recipes. Writes declared tokens into
.uxproof/tokens.json (two additive fields), the rules into the manual section
of conventions.md, a minimal contract.json when none exists, and a theme.css
with the eight identity tokens a prototype directory expects. Stops and routes
to om-ux-setup when a design system already exists; om-ux-setup names it back
when only a proposed palette is available. The generic look's signatures are
an explicit anti-pattern list in the quality gate. Roster, README, docs card,
designer role, upgrade note, and decision entry included.

* feat(om-backlog): epics, stories with acceptance criteria, and tasks from a brief or a spec

New interactive skill. Drafts a tree from product-brief.md (Scope, Key flows,
Goals, Business rules, Non-goals) or a spec's Phasing: epics for the Now items
or Phases, stories as user-facing outcomes with Given/When/Then criteria and
the decision ids they rely on, tasks only where a story needs decomposition.
Ids open every title, stories carry an Epic line, epics a rewritten checklist;
no tracker feature beyond issues, bodies, comments, and labels is assumed.

Every issue is created through om-prepare-issue, so dedupe, SDLC labels, and
the rationale comment are unchanged; existing issues are adopted, never
duplicated. A brief whose problems rest on synthetic or assumed claims is
refused and the research backlog offered instead. The tree is shown and
confirmed before any write. Roster, README, docs card, PM role, upgrade note,
and decision entry included.

* feat(qa-gate): pin qa-approved to the tested head with a QA head line

The comment that grants qa-approved now carries QA head: <sha> — the commit
that was tested. om-auto-qa-pr writes it on --self-qa-signoff; the SDLC.md
template asks QA reviewers for the same line. om-approve-merge-pr reads it
back and, when the PR head moved past it, lists the commits pushed since and
asks for confirmation in the same idiom as its changes-requested confirm.
om-merge-buddy reports a stale sign-off as "QA evidence older than head" and
classifies the PR as almost ready at best. A sign-off without the line is
treated as pre-dating the rule. No new label, no new state.

* feat(qa-gate): self-QA only below risk-high, and one statement across documents

SDLC.md said automation never applies qa-approved, DECISIONS.md said never a
self-granted qa-approved, and om-auto-qa-pr --self-qa-signoff applied it.
The documents now say the one thing the skill does: the self-QA exception is
available to an engineer or to om-auto-qa-pr on risk-low and risk-medium PRs
only, with an evidence list (scenario, environment, test data, result,
negative cases, QA head). On a risk-high PR — labeled, or inferred from a
diff touching auth, sessions, data scoping, money, migrations, or shared
contracts — the skill posts the evidence and withholds the sign-off; a QA
reviewer or a maintainer's stated exception is required, and auth or money
changes need a second person's review regardless. om-approve-merge-pr's
gate explanation matches.

* feat(qa-gate): state matrix and contract conformance are part of QA pass/fail

For a UI surface, om-auto-qa-pr's scenario now carries one required step per
state the change can show — default, empty, loading, error, no-permission,
long content, narrow viewport — and, when .uxproof/ exists, one step for
contract conformance on the changed screens (hardcoded colors where tokens
exist, raw elements where the registry has a component, a screen ignoring
its archetype). A missing or broken state is a FAIL step, not a note.
om-ux-review-pr stays the advisory design review; SDLC.md says which checks
QA owns.

* feat(review): risk-high requires integration evidence for its area

om-code-review gains a risk-high evidence gate next to its test-coverage
step: a PR labeled risk-high, or whose diff touches an area SDLC.md infers
as risk-high (auth and sessions, data scoping, money, schema migrations,
shared contracts), is a blocker without integration-level evidence for that
area — the denied path and wrong-scope read, the failure/retry/idempotency
paths, migration up and down, the consuming side of a contract — unless a
maintainer waives it on the PR. The SDLC.md template replaces "strengthens
the case for deeper review" with an area-to-evidence table, and
om-auto-review-pr's label rules say the rating is not advisory. Upgrade note
and decision entry for the four QA-gate changes included.

* feat(ux-review): the accepted prototype is an acceptance artifact

A spec's UI/UX section may carry a Prototype: line naming the accepted
mockups or an interactive prototype directory. om-ux-review-pr reads the
PR's Source doc spec, opens the linked prototype through the browser
provider beside the running screens, and reports a deviation the spec does
not explain as a [PRODUCT] finding with evidence of both; a deliberate
improvement is a deviation for the author to confirm, never silently
accepted or rejected. The review comment gains a Prototype line. Design-file
review stays out of the collection, recorded under Deferred. The producer
side of the marker lands with the prototype skill (#104).

* docs: the collection now ships forty skills

* feat(om-synthetic-users): panels, fresh runs, pressure, and a parity check

The skill now runs the way the research on synthetic respondents says it
must to mean anything. A panel (--panel, default 5) is resampled every run
(--runs, default 2) from the segments the data names, includes a persona
who barely cares, and runs one persona per fresh-context subagent; a panel
that answers alike is resampled. Only what survived every run is a finding,
with its weight and spread; ties are marked; single-run items sit under
Seen once; saturation is reported.

Interviews ask about the last time and never a stated preference; the
decision is then simulated under the brief's pressures and the record shows
where the story collapses. Each answer carries the fast reaction with its
feeling, then the considered one, and records the research passages that
grounded it. --open runs exploratory interviews that track topics. When real
interview notes exist, the same script runs on the panel and the deviation
is reported as blind spots and questions, logged in calibration.md as a
trend. references/research-basis.md lists the sources, what was adopted, and
what was left out (survey prediction, eye-tracking, personality inventories,
model routing). No numbers from personas; the synthetic label stands.

* feat(om-synthetic-users): measure acquiescence, keep assumptions out of the persona

Two rules from the silicon-crowd study (Science Advances 2024) and the
forecasting literature that followed it. Language models say yes more than
the world does, so the quality gate now counts the panel's yes share on
yes/no questions and excludes unsupported agreement from the findings. A
model handed the hoped-for answer uses it worse than averaging afterwards
would, so the brief's assumptions and expected answers shape the questions
and the pressures but never enter a persona's context. research-basis.md
cites the peer-reviewed version and adds ForecastBench (ICLR 2025), the
prompt-engineering and evaluation-pitfalls papers, and AI-augmented
predictions, each with what was adopted.

* fix(pre-intake): defects found by integration runs of om-discover, om-ux-style, and om-backlog

Each new skill was executed as written against a scratch repository with
real research material; the runs produced the intended artifacts and a list
of instruction defects. This commit closes the ones that would have changed
behavior in a real repository.

om-discover: an explicit --mode is never second-guessed and the team's own
workshop no longer detects the client mode; decisions the user makes in the
session become decision records the brief can cite as documents; an unowned
decision is a proposal with a blocking question, in one rule instead of
three; the own-mode sections (kill criteria, the assumption map's importance
and evidence columns) exist in the template; the quality gate runs before
the skeptic sees the draft; one shape for the Coverage line with a
benchmark bucket and a counting rule; workshop exports tagged by what was
said versus what was decided; a benchmark capture template; round format
without glossary-foreign emoji; Next: none is the right line when material
must be collected first.

om-ux-style: role names unified with tokens.md; a code scan detects a
design system without a contract; the quality gate runs before writing;
Next: none in a repository without components; proposed values marked and
confirmed; no-image and unopened-link cases recorded honestly; the .dark
block's scope stated in the header; kind values and counts defined;
contract-format.md in om-ux-setup documents the design and proposed
sentinels and the theme field.

om-backlog and om-prepare-issue: the readiness stop applies the whole
ticket-level tier, not only assumption-tagged problems; om-prepare-issue
gains --title, --no-spec, and --skip-dedupe so tree ids open titles, no
spec PR is opened per story, and dedupe runs once; body sections handed
over are embedded verbatim; a greenfield exception to the real-paths rule;
dry runs never trigger setup and end with Next: om-backlog <source>; the
research variant files tasks, not stories; story-level labels in the tree;
decisions may produce criteria; "sessions" in the risk inference means
login sessions.

* fix(om-synthetic-users): hold-out parity, bounded transcripts, smaller default panel

The integration run showed two things the report could not have said
better. The parity check scored the panel against the same interview note
that had built four of the six personas, and correctly called its own 9 of
9 overlap leaked; the skill now splits real notes into persona material and
held-out notes (--hold-out, or the newest note per flow), scores only the
held-out ones, and skips the check with the reason stated when nothing can
be held out. Two personas built from one note are one voice twice, so the
second is an assumption persona. And an unbounded run of five-persona
panels took over half an hour on a narrative subject: the default panel is
three, transcripts are budgeted to the script, the report records elapsed
time per phase, and --runs 1 is allowed as an exploration that yields only
seen-once items.

* fix(om-synthetic-users): defects from the integration run's full report

The subagent hand-off is now specified: a general-purpose subagent with no
tools, given the persona block with evidence tags stripped, a subject
excerpt that excludes the brief's assumptions, goals, hypotheses, and open
questions, and the script with passages attached per question and marked
as background, not memory; retelling a passage as one's own or relaying
what "people like me" report is flagged and carries no finding. One
confirmation stop before any subagent runs (composition, flow mapping,
stance). A flow name that matches no heading is mapped and confirmed;
report and transcript names use a kebab-case slug. Four balanced
past-behaviour yes/no questions make the acquiescence measure operational.
Saturation is measured over the last three interviews or twenty topics;
ties use the larger spread; the discard rule is per interview, a whole run
only when every persona agreed. Assumptions the panel's segment cannot
answer are listed as not askable. Unquantified pressures are applied as
unstated, never invented. The indifferent seat's salience may be an
assumption and says so; passage-quoted quantities are allowed, invented
ones dropped. Header and contract line shapes no longer collide.

* feat(om-discover): --quick pass and bounded rounds

A full run asked as many questions as the frontier held (eleven in the
integration run), dispatched a skeptic subagent that re-read the whole
research directory, and wrote every template up front. Rounds are now at
most eight questions, two rounds the norm and three the ceiling; the
skeptic subagent gets the draft and the source list, not the directory;
templates are written only for entries the collection plan names. --quick
runs one round, the skeptic as an inline checklist, the critical gate items
only, and writes the ticket-level sections with the rest on the collection
plan, for first passes, lessons, and tests. Reports carry Elapsed per step.

* fix(om-discover): align coverage shape, step numbers, and pre-confirmation writes across references

* fix(om-discover, om-backlog): one coverage shape in the header, assumption result vocabulary, dry-run never runs setup, criteria shown in full before filing

* feat(om-discover): hand off to the next step after the brief; housekeeping out of the round

* fix(om-discover): the mode is confirmed before the gate, never as a round question

* feat(om-discover): one voice for the interviewer and the skeptic; questions in plain words with an example answer

* fix: preserve pre-intake identities and handoff contracts

* fix(om-discover): ask neutral questions and qualify recommendations

* feat(om-discovery-setup): the product layer is opt-in, added by its own setup

The Discovery stage, the Definition of Ready, the product roles, and the
protected product decisions move behind `IF discovery` in the SDLC template
and are written into an existing SDLC.md by the new om-discovery-setup skill,
between discovery:start/end markers, so a re-run is idempotent and a template
change is a --refresh. om-setup-agent-pipeline never asks about the layer; a
fresh setup renders the delivery-only document with om-brainstorm as the
pre-ticket step.

The intake skills no longer fall back to a built-in Definition of Ready:
om-auto-manage-issues records READY_STATUS n/a, om-auto-fix-issue's feature
route skips the gate, and om-backlog skips the readiness check and says so,
whenever SDLC.md has no such section. The product skills keep running without
the setup and mention it once in their reports; only om-discovery-setup runs
the delivery setup when it is missing.

Roles settled against the market: Product owner is always part of the layer,
Domain expert and Designer are flags, the Reviewer line carries the tech-lead
duties (second person on risk-high, spec sign-off), the Maintainer owns the
installed skills and acts as release manager unless one is named.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Wn4uCwRHXeknwj2s91JWW

* refactor: rename om-discovery-setup to om-setup-discovery-pipeline

It edits the pipeline files om-setup-agent-pipeline owns (the config and
SDLC.md), so it is that skill's counterpart, not om-ux-setup's, and the two
names now read as a pair.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Wn4uCwRHXeknwj2s91JWW

* fix(om-setup-discovery-pipeline): defects from the first run on a lesson-3 repository

A run on an SDLC.md generated from the pre-discovery template left the old
Intake row under the new pair, placed the Definition of Ready before the
validation gate because the after-merge paragraph it anchored on did not
exist, and put marker lines inside the lifecycle table, which breaks a GFM
table. Rows are now replaced by stage name (an Intake row that does not
mention the Definition of Ready is the delivery-only row, whatever its
wording), the two sections anchor on the first of the section headings that
exists, and rows and bullets carry an inline <!-- discovery --> marker
instead of marker lines.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Wn4uCwRHXeknwj2s91JWW

* feat(om-setup-discovery-pipeline): one voice for the questions and the confirmation

The first interactive run asked in the skill's own vocabulary — "delivery-only
Intake row", "marked blocks", "byte-for-byte", "amending block" — the same
defect om-discover fixed on 2026-09-03. A voice reference now binds the two
questions, the pre-write confirmation, and the report to the user's language:
say what they will see in SDLC.md, the one row that is rewritten and what it
said before, what is left alone and why; one thing per question, with a
default and what the answer changes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Wn4uCwRHXeknwj2s91JWW

* fix(om-setup-discovery-pipeline): report length target; never advise re-running om-setup-agent-pipeline to refresh an existing SDLC.md

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Wn4uCwRHXeknwj2s91JWW

* fix(pre-intake): preserve contracts while rebasing onto current base

* feat(discovery): add neutral prototypes before brief refresh

* fix(om-discover): clarify questions, briefs, and handoffs

* fix(skills): make discovery and QA contracts executable

---------

Co-authored-by: Maciej Gren <maciej.gren@gmail.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Piotr Karwatka <piotr@catchthetornado.com>
Co-authored-by: Piotr Karwatka <piotr.karwatka@gmail.com>
2026-09-14 10:44:20 +02:00
..