featureparity 0.0.27 → 0.0.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/lib/fp/cli.rb +14 -2
  3. data/lib/fp/client.rb +79 -2
  4. data/lib/fp/commands/analyze.rb +17 -0
  5. data/lib/fp/commands/base.rb +16 -0
  6. data/lib/fp/commands/check.rb +38 -4
  7. data/lib/fp/commands/ci_report.rb +2 -2
  8. data/lib/fp/commands/comment.rb +1 -1
  9. data/lib/fp/commands/comments.rb +146 -0
  10. data/lib/fp/commands/coverage.rb +149 -0
  11. data/lib/fp/commands/doctor.rb +228 -0
  12. data/lib/fp/commands/help.rb +41 -1
  13. data/lib/fp/commands/history.rb +16 -1
  14. data/lib/fp/commands/init.rb +181 -117
  15. data/lib/fp/commands/list.rb +58 -4
  16. data/lib/fp/commands/mark.rb +167 -0
  17. data/lib/fp/commands/projects.rb +6 -1
  18. data/lib/fp/commands/propose.rb +435 -53
  19. data/lib/fp/commands/propose_change.rb +13 -7
  20. data/lib/fp/commands/question.rb +137 -0
  21. data/lib/fp/commands/report.rb +40 -4
  22. data/lib/fp/commands/run.rb +147 -0
  23. data/lib/fp/commands/show.rb +41 -3
  24. data/lib/fp/commands/spot_check.rb +458 -0
  25. data/lib/fp/commands/tutorial.rb +95 -0
  26. data/lib/fp/commands/whoami.rb +2 -0
  27. data/lib/fp/commands.rb +8 -0
  28. data/lib/fp/config.rb +12 -0
  29. data/lib/fp/junit.rb +74 -11
  30. data/lib/fp/repo_detector.rb +488 -0
  31. data/lib/fp/requirement_lint.rb +105 -0
  32. data/lib/fp/rspec_json.rb +54 -0
  33. data/lib/fp/tutorial/hexhaven/AGENTS.md +5 -0
  34. data/lib/fp/tutorial/hexhaven/README.md +29 -0
  35. data/lib/fp/tutorial/hexhaven/lib/hexhaven.rb +36 -0
  36. data/lib/fp/tutorial/hexhaven/test/junit_reporter.rb +134 -0
  37. data/lib/fp/tutorial/hexhaven/test/rules_test.rb +36 -0
  38. data/lib/fp/tutorial/hexhaven/test/test_helper.rb +6 -0
  39. data/lib/fp/version.rb +1 -1
  40. data/lib/fp.rb +1 -0
  41. data/skills/fp/SKILL.md +244 -105
  42. data/skills/fp/references/cli.md +304 -3
  43. metadata +19 -2
data/skills/fp/SKILL.md CHANGED
@@ -17,6 +17,14 @@ command -v fp && fp --version
17
17
  ```
18
18
 
19
19
  If missing: `gem install featureparity` (or `bundle exec fp` inside an app that already depends on the gem).
20
+ `fp doctor` checks the install, the config and the repo without an API key. If `fp` fails
21
+ inside a repo but works elsewhere, see Troubleshooting.
22
+
23
+ **Already read the repo's FeatureParity section?** `fp init` writes one into `AGENTS.md`
24
+ (or `CLAUDE.md`), and it carries the modeling rules (§1), the requirement-writing standard
25
+ (§5), onboarding and troubleshooting from this file word for word, between the same
26
+ `fp-shared` comments. This file is their source. Skip those blocks if you've read them
27
+ there; the rest of this skill is the command reference.
20
28
 
21
29
  ## Non-interactive rules
22
30
 
@@ -49,6 +57,8 @@ every project the user belongs to; never ask for a per-project key.
49
57
  fp list --project stowzilla # All active requirements
50
58
  fp list --project stowzilla --status draft # Proposed work; avoid duplicates
51
59
  fp list --project stowzilla --gaps # Requirements with a required surface lacking evidence
60
+ fp list --project stowzilla --status draft --gaps # Drafts with a required surface lacking evidence
61
+ fp coverage --project stowzilla # Drafts × surfaces, then the drafts with no evidence
52
62
  fp show <slug> --project stowzilla # Requirement details and evidence
53
63
  fp history <slug> --project stowzilla # Origins and pending changes
54
64
  fp changes --source-url <work-item-url> # Activity prompted by one card, issue, or thread
@@ -57,25 +67,32 @@ fp matrix --project stowzilla --csv # Export as CSV
57
67
  fp check --project stowzilla # Enforce parity (exits 1 on violations)
58
68
  ```
59
69
 
60
- Treat FeatureParity as the human-readable product specification, not a bookkeeping step.
61
- Before coding, inventory the entire request: user-visible behaviours, policies, limits,
62
- plans, deadlines, state transitions, permissions, failure modes, and affected surfaces.
63
- Compare all of it with active and draft requirements, including adjacent requirements the
64
- change might make inaccurate.
65
-
66
- Model that scope deliberately:
67
-
68
- - One independently testable or independently failable product promise per focused
69
- requirement. Split an acceptance sentence when its clauses could pass or fail separately.
70
- - Use a parent for a broad capability and children for distinct behaviours, policies, or
71
- surface-specific promises. Do not model implementation details with no product promise.
72
- - Record concrete decisions such as prices, quotas, dates, roles, and fallbacks in acceptance
73
- criteria rather than leaving them as assumptions in code or a pull request.
74
- - Propose changes to existing requirements whose meaning moved; adding a new requirement is
75
- not enough if it leaves an old one false.
76
- - Reconcile again before finishing: every shipped behaviour maps to a current requirement,
77
- every changed promise is recorded, and every focused requirement has marked evidence or
78
- remains an explicit gap. Never let one broad marker imply coverage of untested clauses.
70
+ <!-- fp-shared:begin modeling -->
71
+ **The requirement catalog is the human-readable product specification, not a box to
72
+ tick with one umbrella record.** It records the team's current shared understanding;
73
+ it is not a finished decree handed from product to engineering. Refine requirements
74
+ through ongoing conversation with customers, domain experts, and builders. The human
75
+ product owner decides value and priority; agents should surface gaps, inconsistencies,
76
+ alternatives, and useful splits rather than silently making product decisions.
77
+
78
+ Before coding, enumerate the independently meaningful promises in the request:
79
+ user-visible behaviours, policies, limits, plans, deadlines, state transitions,
80
+ permissions, failure modes, and affected surfaces. Then model them:
81
+
82
+ - Give each independently testable or independently failable product promise its own
83
+ focused requirement. If one acceptance sentence joins behaviours that could pass or
84
+ fail separately, split it.
85
+ - Use a parent for the broad capability and children for distinct behaviours, policies,
86
+ or surface-specific promises. Do not create requirements for implementation details
87
+ or refactors that make no product promise.
88
+ - Put concrete product decisions — prices, quotas, dates, roles, fallbacks — in the
89
+ requirement acceptance criteria. Never leave them only as assumptions in code or a PR.
90
+ - Check adjacent requirements and their history. New requirements do not excuse an old
91
+ requirement that the work makes inaccurate; propose a change to keep the whole catalog true.
92
+ - Before finishing, reconcile the implementation against the catalog: every shipped
93
+ behaviour maps to a current requirement, every changed promise is recorded, and every
94
+ focused requirement has appropriate marked evidence or an explicit gap. A broad marker
95
+ must never appear to prove several acceptance clauses that its test does not exercise.
79
96
 
80
97
  **Prevent contradictions before they enter the catalog.** Before proposing a new or changed
81
98
  promise, compare its intended acceptance criteria with related active and draft requirements
@@ -83,31 +100,35 @@ and read their history. Ask whether both promises can be true at the same time f
83
100
  user, state, and conditions. If not, do not add another requirement.
84
101
 
85
102
  A failing test bound to an existing requirement, or an implementation that only works by
86
- changing one, is a contradiction signal — not permission to weaken the test or write a second
87
- requirement around it. Identify which promise matches product intent, then use
88
- `fp propose-change` (or `--removal`) with the source and reason to put that decision before a
89
- human. If the intent is unclear, stop and ask rather than making the catalog say both things.
103
+ changing one, is a contradiction signal — not permission to weaken the test or write a
104
+ second requirement around it. Identify which promise matches product intent, then use
105
+ `fp propose-change` (or `--removal`) with the source and reason to put that decision before
106
+ a human. If the intent is unclear, stop and ask rather than making the catalog say both things.
90
107
 
91
108
  **Treat existing tests as protected product evidence.** Before editing an existing test,
92
109
  determine what expectation it already records and whether CI has passing evidence for it.
93
110
 
94
- - If the test backs passing evidence, do not rewrite it to make the current implementation or a
95
- new requirement fit. Explicitly flag the intended test edit in the work item and pull request.
96
- If its expected behaviour would change, propose the requirement change and wait for explicit
97
- human approval before editing the test; a newly green run must not hide that the proof changed.
98
- - When FeatureParity reports a changed bound test, run `fp changed-tests` (or add `--json`) and
99
- compare its accepted and candidate revisions with the requirement. Record a plain-language
100
- assessment for the exact candidate fingerprint with `fp changed-tests assess`: `still_proves`
101
- resolves only that fingerprint; `no_longer_proves` and `uncertain` remain open for a human
102
- product decision. A later fingerprint always needs a new assessment.
103
- - A new requirement does not retroactively own or supersede a pre-existing failing test, whether
104
- it is draft or active. Do not change that test, or adopt it as the new requirement's proof,
105
- merely to make new work pass. Surface the conflict and wait for explicit human approval to
106
- change the existing expectation.
107
-
108
- A changed-test finding is an audit signal alongside the independent CI outcome, not a failed
109
- test. It is also separate from `suspect`, which means requirement wording changed and its
110
- evidence needs re-verification. Neither permits rewriting a test before product intent is decided.
111
+ - If the test backs passing evidence, do not rewrite it to make the current implementation
112
+ or a new requirement fit. Explicitly flag the intended test edit in the work item and pull
113
+ request. If its expected behaviour would change, propose the requirement change and wait
114
+ for explicit human approval before editing the test; a newly green run must not hide that
115
+ the proof itself changed.
116
+ - When FeatureParity reports a changed bound test, run `fp changed-tests` (or add `--json`)
117
+ and compare the accepted and candidate source revisions with the requirement. Record the
118
+ exact candidate through `fp changed-tests assess <id> --candidate-fingerprint <sha256>`
119
+ with a plain-language explanation and one classification: `still_proves`,
120
+ `no_longer_proves`, or `uncertain`. The first resolves only that fingerprint; the others
121
+ remain open for a human product decision. A later fingerprint needs a new assessment.
122
+ - A new requirement does not retroactively own or supersede a pre-existing failing test —
123
+ whether the requirement is draft or active. Do not change that test, or adopt it as the new
124
+ requirement's proof, merely to make the new work pass. Surface the conflict and wait for
125
+ explicit human approval to change the existing expectation.
126
+
127
+ A changed-test finding is an audit signal alongside the testcase's independent CI outcome.
128
+ It is not a failed test and is separate from `suspect`, which means requirement wording
129
+ changed and its evidence needs re-verification. Neither permits rewriting a test before
130
+ product intent is decided.
131
+ <!-- fp-shared:end modeling -->
111
132
 
112
133
  ### 2. Add the fp:<slug> marker to tests
113
134
 
@@ -151,16 +172,26 @@ first CI run, or local work where CI isn't wired up. When you do report over a C
151
172
  cell anyway, `fp report` now tells you it was superseded (the status stays CI's, your
152
173
  report lands as metadata only) so you can see the no-op instead of assuming it took.
153
174
 
154
- ### 4. Report evidence from JUnit XML (batch upload without CI)
175
+ ### 4. Report evidence from a test run (batch upload without CI)
176
+
177
+ When CI isn't available, run the suite locally and upload the report. `fp run` adds a
178
+ report formatter to rspec, pytest, vitest or playwright itself, so the project needs no
179
+ new dependency, then reports exactly as `fp report --junit` would:
180
+
181
+ ```bash
182
+ fp run --surface api --repo stowzilla/marketplace \
183
+ --work-item https://app.fizzy.do/123/cards/456 -- bundle exec rspec
184
+ ```
155
185
 
156
- When CI isn't available, run the suite locally and upload the report:
186
+ Or make the report yourself. `--junit` takes JUnit XML or RSpec's built-in JSON, which
187
+ needs no extra gem (`fp init --detect` prints the command for each runner it finds):
157
188
 
158
189
  ```bash
159
- # 1. Generate JUnit XML
160
- rspec --format RspecJunitFormatter --out junit.xml
190
+ # 1. Write a report
191
+ bundle exec rspec --format progress --format json --out rspec.json
161
192
 
162
193
  # 2. Upload — one call covers every marked test
163
- fp report --junit junit.xml \
194
+ fp report --junit rspec.json \
164
195
  --project stowzilla \
165
196
  --surface api \
166
197
  --repo stowzilla/marketplace \
@@ -173,79 +204,95 @@ fp report --junit junit.xml \
173
204
  - `--surface` is the default; markers can override with `@suffix`
174
205
  - `--base-dir DIR` sets where relative paths resolve from
175
206
 
207
+ #### Optional: attach screenshots and video, with permission
208
+
209
+ <!-- fp-shared:begin media -->
210
+ **Media is optional, and only with permission.** A test that drives a user interface can
211
+ carry the screenshots and videos it recorded as visual evidence, shown under that test's
212
+ receipt on the requirement page. Nothing requires it: a receipt counts the same with or
213
+ without media, and a capture never changes a cell's state. Uploading stores the files in
214
+ FeatureParity, so:
215
+
216
+ - **Ask first.** Upload only when the person you're working for has said yes, for this
217
+ project. Don't do it by default, and don't take "the run recorded something" as permission.
218
+ - **Never capture someone's own screen.** No screenshots or recordings of their desktop,
219
+ terminal, browser session or other windows. Only what an automated test drove (a
220
+ Playwright browser, a simulator or emulator the test launched) can be attached, and only
221
+ with that permission.
222
+ - **Look before you upload.** Don't attach a capture that shows real people's data, secrets
223
+ or anything outside the test.
224
+
225
+ When you have the go-ahead:
226
+
227
+ - **Playwright** lists its recorded files in the JUnit report as `[[ATTACHMENT|…]]`.
228
+ `fp report --junit results.xml --surface web --repo <org/repo> --attach-media` uploads
229
+ one set per bound test, titled with the test's name. It also works with `fp run ... -- npx playwright test`.
230
+ Without `--attach-media`, nothing is uploaded; fp only says how many captures it found.
231
+ - **One capture from a test** (for example an XCUITest or Espresso recording):
232
+ `fp attach <slug> <file> --surface <surface> --example-title "<test name>"`.
233
+ - png, jpg, gif, webp, mp4, webm or mov, up to 100 MB. `fp attachments <slug>` lists them;
234
+ `fp attach rm <slug> <id>` removes one.
235
+ <!-- fp-shared:end media -->
236
+
176
237
  ### 5. Write and propose decision-ready requirements
177
238
 
178
- A requirement is a product decision a reviewer can approve, not a design task for an
179
- engineer to carry out. It should sound like a capable teammate wrote it: natural, direct,
180
- and specific enough to protect an outcome without dictating an accidental solution.
181
-
182
- Treat the catalog as the current record of shared understanding, not a finished specification
183
- handed from a product owner to implementers. Requirements are discovered and refined through
184
- ongoing conversation among customers, domain experts, and builders. The human product owner
185
- makes the final value and priority decisions; agents participate by exposing gaps,
186
- inconsistencies, alternatives, and useful splits. Prefer customer outcomes over devotion to a
187
- feature list.
188
-
189
- Before drafting:
190
-
191
- - Learn from the request, related requirements and history, support reports, research, and
192
- observed user behaviour when available. Look for what people attempt, where they abandon a
193
- task, what they actually use, and what experiments reveal. That evidence may expose a
194
- different need from the first solution they suggested.
195
- - Separate facts and decided policy from open questions. Never turn a missing decision into
196
- a plausible-sounding price, quota, timeout, count, date, role, or fallback. Ask when the
197
- answer changes the product promise.
198
- - Identify the actor, the situation that triggers the need, the valuable outcome, and material
199
- boundaries such as permissions, failures, and affected surfaces.
200
- - Keep one independently failable promise per requirement. Use a parent and focused children
201
- when a capability contains several decisions.
202
-
203
- Write each field for a reviewer, not for the implementation:
204
-
205
- - **Title:** one clear product promise in present tense, with a concrete subject and active
206
- verb. Name the capability or outcome, not the project (`Dispatchers see current shipment
207
- status`, not `Implement status polling`).
208
- - **Why:** one natural sentence saying who needs this, the problem or risk, and the outcome
209
- worth protecting. Do not repeat the title, narrate the request or bug history, advertise
210
- the feature, or explain how it will be built. Delete AI filler such as “ensure a seamless,
211
- robust experience.”
212
- - **Acceptance:** one independently verifiable rule of observable behaviour that lets someone
213
- decide whether the promise is true. State the relevant trigger or situation, the result, and
214
- material boundaries that qualify that same promise. Given/When/Then may clarify those parts, but it
215
- is not a mandatory template. Split a second result that could fail independently into its
216
- own requirement instead of comma-chaining it here.
217
- - **Example:** supply one concise concrete case that would pass the general rule, and put it
218
- after the rule in Acceptance as `Example: ...`. Use the domain's real terms and
219
- representative data, but ask rather than invent consequential policy. Do not mistake a few
220
- examples for the rule or let executable tests stand for every case; neither replaces the
221
- general rule and continued conversation.
222
- - **Numbers and policy:** include a number only when the source made it a real product decision
223
- or an external constraint requires it. Do not invent implementation defaults and present
224
- them as scope.
225
- - **Implementation detail:** omit components, data models, algorithms, endpoints, polling
226
- intervals, and UI controls unless that interface or constraint is itself user-visible policy.
239
+ <!-- fp-shared:begin writing -->
240
+ **Write a requirement as a product decision someone can approve, not as a design
241
+ task.** It should read like a capable teammate wrote it: direct, specific, and free
242
+ of boilerplate such as “ensure a seamless experience.”
243
+
244
+ - **Title:** one clear product promise in present tense, with a concrete subject and
245
+ active verb. Name the user-visible capability, not the work (`“Dispatchers see
246
+ current shipment status”`, not `“Implement status polling”`).
247
+ - **Why:** one natural sentence naming who needs this, the problem or risk, and the
248
+ outcome worth protecting. Do not repeat the title, narrate the request or bug
249
+ history, sell the feature, or explain the mechanism.
250
+ - **Acceptance:** one independently verifiable rule of observable behaviour that lets a
251
+ reviewer decide whether the promise is true. State the trigger or situation, the result, and material
252
+ boundaries that qualify that same promise. Given/When/Then may clarify those parts,
253
+ but it is not a mandatory template. Split a second result that could fail
254
+ independently into its own requirement instead of comma-chaining it here.
255
+ - **Example:** supply one concise concrete case that would pass the general rule, and
256
+ put it after the rule in Acceptance as `Example: ...`. Use the domain's real terms
257
+ and representative data, but ask rather than invent consequential policy. Do not mistake a few examples for the rule
258
+ or let marked tests stand for every case; neither replaces the general rule and
259
+ continued conversation.
260
+ - **Numbers and policy:** include a price, limit, timeout, date, role, or fallback only
261
+ when the source made it a real product decision or an external constraint requires it.
262
+ Never invent a plausible value to fill a gap. If the decision matters and the source is
263
+ silent, ask.
264
+ - **Implementation detail:** leave out components, data models, algorithms, endpoints,
265
+ and UI controls unless that interface or constraint is itself part of the promise.
266
+
267
+ Learn from the request, existing requirements and history, and available evidence about
268
+ what users actually do. Look for what they attempt, where they abandon a task, what they
269
+ use, and what experiments reveal. Treat the first proposed solution as input, not
270
+ unquestionable scope. Preserve important uncertainty as a question rather than
271
+ laundering a guess into acceptance criteria.
227
272
 
228
273
  State the promise itself rather than commentary about it. Avoid openings such as “This
229
274
  feature…”, “This requirement…”, “The goal is…”, “Users should be able to…”, and “The
230
275
  system should…”. Use the real actor or product as the subject and an active verb.
231
276
 
232
- A good requirement is concise, not merely short. Keep every sentence that changes a decision;
233
- remove everything that only sounds thorough.
234
-
235
277
  - ✅ **Title:** `Dispatchers see current shipment status`
236
278
  **Why:** `Dispatchers need to spot delayed shipments before they miss a delivery window.`
237
279
  **Acceptance:** `When a shipment's status changes, the dashboard shows the new status; if status is unavailable, it says so instead of presenting stale data as current.`
238
280
  - ❌ **Title:** `Implement Redis-backed 30-second status polling`
239
281
  **Why:** `This important feature ensures a seamless, robust experience.`
240
282
  **Acceptance:** `Use a background worker and refresh every 30 seconds.`
241
- This invents policy, prescribes a design, and never states the outcome.
283
+ This invents policy, prescribes a design, and never states the product outcome.
242
284
 
243
- Before saving, answer three questions against the actual fields: Who is this promise for? How
244
- would the concrete example prove it done? Why does the outcome matter? If any answer is missing
245
- or vague, revise the draft or ask the user. Then read it as a manager deciding scope: Is the
246
- value clear? Can the result be observed? Are real product decisions distinguished from guesses?
247
- Could every clause fail independently and, if so, should it be split? Does every sentence earn
248
- its place? Do not create the record until the draft passes this review.
285
+ A good requirement is concise, not merely short: keep every sentence that changes a
286
+ decision and remove everything that only sounds thorough.
287
+
288
+ Before proposing, answer three questions against the actual fields: Who is this promise
289
+ for? How would the concrete example prove it done? Why does the outcome matter? If any
290
+ answer is missing or vague, revise the draft or ask the user. Then read it as a manager deciding scope:
291
+ is the value clear, can the result be observed, are product decisions
292
+ distinguished from guesses, could any clause fail on its own (then split it), and does
293
+ every sentence earn its place? If the draft fails
294
+ this review, revise it or ask before writing the record.
295
+ <!-- fp-shared:end writing -->
249
296
 
250
297
  Then create the proposal as a draft:
251
298
 
@@ -262,6 +309,37 @@ fp propose --project stowzilla \
262
309
 
263
310
  **Agents always create requirements as draft.** A human must activate them in the web app.
264
311
 
312
+ When no card or issue prompted it — you wrote the requirement by reading the code, as when
313
+ onboarding a repo — pass `--source-type repo_scan` and one `--source-ref path:line` for each
314
+ place you read it from.
315
+
316
+ Proposing several at once? Put them in a YAML file and run `fp propose --file reqs.yml
317
+ --dry-run` first. It lints every entry's wording and checks slugs and parents against the
318
+ catalog without writing anything. Then run it without `--dry-run`: the batch is created only if
319
+ every entry is valid. Bind tests with `fp mark <slug> <file>:<line>` rather than typing
320
+ markers by hand.
321
+
322
+ **Confirm draft coverage with `fp coverage`.** The gate measures only active requirements,
323
+ so while everything you proposed is still a draft `fp check` says "Nothing to enforce yet"
324
+ and `fp list --gaps` finds nothing. `fp coverage` shows each draft × surface resolved from
325
+ the evidence you reported, and ends with the drafts that have no evidence on a required
326
+ surface — hand that list to the human as the requirements with no test yet. Drafts are
327
+ reported, never gated. `fp check --include-drafts` appends the same table to the verdict.
328
+
329
+ **Attach your questions to the drafts they concern.** When a draft leaves a decision only a
330
+ human can make (a limit the source never set, a role it didn't name), don't leave the question
331
+ in chat, where it's cut off from the draft. Ask it on the draft:
332
+
333
+ ```bash
334
+ fp question upload_limits "Is the 5 MB cap per file or per upload?"
335
+ fp questions upload_limits # open and answered questions, with the answers
336
+ ```
337
+
338
+ The human reviewing that draft in Quick Review sees the question beside it and answers or
339
+ dismisses it there; `fp show` lists the open ones. Agents can ask but never answer. If the
340
+ user asks you for "a list of questions for the human", ask each one on its draft and give
341
+ them the list too. Draft and active requirements take questions.
342
+
265
343
  ### 6. Propose a change to an existing requirement
266
344
 
267
345
  When a requirement no longer says the right thing, don't silently edit it — propose the
@@ -464,6 +542,40 @@ the command relays the upgrade message if that's used up. `fp projects delete` e
464
542
  asks a human to type the slug back (or `--yes` in scripts) and is owner-only — don't reach
465
543
  for it to tidy up; a project's requirements, evidence, and history go with it.
466
544
 
545
+ ### Onboarding a repo (first run)
546
+
547
+ <!-- fp-shared:begin onboarding -->
548
+ The per-task loop assumes a catalog already describes the product. On a repo's first run
549
+ there isn't one yet, so the job is to write it down, as drafts a human activates, rather
550
+ than to check work against it.
551
+
552
+ 1. `fp doctor` confirms fp runs under the repo's Ruby and shows which API it writes to,
553
+ then lists the repo's test runners, database and devcontainer.
554
+ 2. `fp init --detect` suggests a project slug, surfaces, and the command that makes each
555
+ test runner write a report. If the project doesn't exist yet, create it with
556
+ `fp projects create <slug> --name "..." --surfaces <keys>`, then run
557
+ `fp init --project <slug>`.
558
+ 3. Pick surfaces by this rubric, not by the folder layout. A surface is somewhere a user
559
+ interacts with the product: a web app, an iOS or Android app, a desktop app, a CLI, or
560
+ an API that customers call directly. An internal API with no separate client is not
561
+ one; its tests are evidence for the surface the user touches.
562
+ 4. Propose what the code already promises as drafts, written to the requirement-writing
563
+ standard. Review a batch with `fp propose --file <file> --dry-run`, then send it without
564
+ `--dry-run`. Pass `--source-type repo_scan` and name the files you read in
565
+ `--source-context`.
566
+ 5. Bind the tests that already prove each draft with `fp mark <slug> <file>:<line>`, or
567
+ write the `fp:<slug>` comment yourself.
568
+ 6. Report with `fp run --surface <key> --repo <org/repo> -- <test command>`. It adds the
569
+ report formatter for rspec, pytest, vitest and playwright, so the project needs no new
570
+ dependency. For any other runner, use `fp report --junit <file>`.
571
+ 7. `fp coverage` lists the drafts that still have no evidence. When the code doesn't settle
572
+ a product decision (a limit, a role, a fallback), attach the question to the draft with
573
+ `fp question <slug> "<text>"` instead of guessing an answer.
574
+ 8. Commit `.featureparity.yml`, the workflow and the agent docs. Committing the workflow
575
+ before anyone has added the `FP_API_KEY` secret is fine: the gate skips with an
576
+ explanation and the build stays green until the secret exists.
577
+ <!-- fp-shared:end onboarding -->
578
+
467
579
  ### Triage requirement quality (`fp analyze`)
468
580
 
469
581
  `fp analyze` checks how well requirements are written and whether they belong in the
@@ -495,20 +607,47 @@ not as the fix — you still write the proposal.
495
607
  | Not a product promise / not observable | A human decides whether it belongs; don't guess |
496
608
  | Missing why, vague acceptance, implementation detail, boilerplate | `fp propose-change <slug> --why "..." --acceptance "..."` |
497
609
 
610
+ ## Troubleshooting
611
+
612
+ <!-- fp-shared:begin troubleshooting -->
613
+ - **`mise ERROR No version is set for shim: fp`** inside a repo, while `fp` works from
614
+ another directory (rbenv and asdf say `fp` isn't installed): the repo pins a Ruby in
615
+ `.ruby-version`, `.tool-versions` or `mise.toml` that the featureparity gem isn't
616
+ installed under. The version manager's shim fails before fp starts, so fp can't diagnose
617
+ it from inside. Install the gem under the pinned Ruby by running `gem install featureparity`
618
+ inside the repo (`mise exec -- gem install featureparity` with mise), or put the bin
619
+ directory of the Ruby that has it first on `PATH`. `fp doctor`, run from anywhere fp
620
+ works, prints the exact commands.
621
+ - **The tests need a database.** `fp doctor` says whether they do (pg or mysql gems,
622
+ `config/database.yml`, docker-compose) and whether a `.devcontainer` can provide one. The
623
+ generated CI workflow has no database service, so add one to its report job.
624
+ - **The runner can't write JUnit without a new dependency.** RSpec's own
625
+ `--format json --out rspec.json` report is accepted anywhere `--junit` is, and `fp run`
626
+ adds the formatter for rspec, pytest, vitest and playwright itself.
627
+ <!-- fp-shared:end troubleshooting -->
628
+
498
629
  ## Quick reference
499
630
 
500
631
  | Task | Command |
501
632
  |------|---------|
633
+ | Check fp, config and the repo | `fp doctor` |
634
+ | Suggest slug, surfaces, test commands | `fp init --detect` |
502
635
  | Onboard a repo | `fp init --project X` |
503
636
  | List requirements | `fp list --project X` |
504
637
  | Show gaps | `fp list --project X --gaps` |
638
+ | Draft coverage | `fp coverage --project X` |
505
639
  | Show details | `fp show <slug> --project X` |
506
640
  | Report evidence | `fp report <slug> --project X --surface Y --file Z --repo A/B` |
507
- | Report from JUnit | `fp report --junit file.xml --project X --surface Y --repo A/B` |
641
+ | Report from JUnit / RSpec JSON | `fp report --junit file.xml --project X --surface Y --repo A/B` |
642
+ | Upload a run's screenshots/videos (optional, with permission) | `fp report --junit results.xml ... --attach-media` |
643
+ | Attach a test's capture (optional, with permission) | `fp attach <slug> <file> --project X --surface Y --example-title "<test name>"` |
644
+ | Run tests and report | `fp run --surface Y --repo A/B -- bundle exec rspec` |
508
645
  | Propose requirement | `fp propose --project X --slug Y --name "..."` |
509
646
  | Propose a change | `fp propose-change <slug> --project X --why "..." --reason "..."` |
510
647
  | Propose a deletion | `fp propose-change <slug> --project X --removal --reason "..."` |
511
648
  | View change history | `fp history <slug> --project X` |
649
+ | Ask a human about a draft | `fp question <slug> "..." --project X` |
650
+ | Read a draft's questions and answers | `fp questions <slug> --project X` |
512
651
  | Triage requirement quality | `fp analyze --project X` |
513
652
  | View work-item activity | `fp changes --project X --source-url URL` |
514
653
  | Enforce parity | `fp check --project X` |