specrails-core 1.7.0 → 1.7.2
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.
- package/bin/specrails-core.js +24 -7
- package/docs/README.md +37 -0
- package/docs/agents.md +273 -0
- package/docs/api-reference.md +266 -0
- package/docs/changelog.md +151 -0
- package/docs/concepts.md +183 -0
- package/docs/customization.md +320 -0
- package/docs/deployment.md +217 -0
- package/docs/getting-started.md +107 -0
- package/docs/installation.md +243 -0
- package/docs/playbook-oss-maintainer.md +112 -0
- package/docs/playbook-parallel-dev.md +124 -0
- package/docs/playbook-product-discovery.md +115 -0
- package/docs/updating.md +96 -0
- package/docs/workflows.md +410 -0
- package/install.sh +6 -0
- package/package.json +2 -1
- package/update.sh +11 -11
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Parallel Development
|
|
2
|
+
|
|
3
|
+
> For maintainers shipping multiple features in a sprint who want to maximize throughput without introducing merge conflicts.
|
|
4
|
+
|
|
5
|
+
## How specrails parallelizes work
|
|
6
|
+
|
|
7
|
+
When you pass multiple issue numbers to `/sr:batch-implement`, specrails spawns one git worktree per feature. Each worktree has its own branch, its own isolated copy of the working tree, and its own full agent pipeline running concurrently. Features do not queue — they run in parallel from Phase 3a (Architecture) through Phase 5 (PR creation).
|
|
8
|
+
|
|
9
|
+
This is not a simulation of parallelism. Each pipeline is a separate Claude Code session with no shared state. The Architect for issue #71 has no visibility into the Architect for issue #63. Each Developer commits to its own branch. Each Reviewer runs CI independently. The worktrees are merged into the base branch at the end of the batch run.
|
|
10
|
+
|
|
11
|
+
The speed advantage over sequential implementation is significant. For a batch of three medium-effort features, sequential implementation might take 90 minutes. Parallel implementation takes roughly as long as the slowest single feature — often 30–40 minutes. The constraint is wall-clock time, not the number of features.
|
|
12
|
+
|
|
13
|
+
## What's safe to parallelize
|
|
14
|
+
|
|
15
|
+
Not every combination of features is safe to run in parallel. A feature is safe to include in a parallel batch when all four conditions hold:
|
|
16
|
+
|
|
17
|
+
1. **File isolation**: the feature touches different files from the other features in the batch. Two features that both modify `src/api/middleware.ts` will produce a merge conflict.
|
|
18
|
+
|
|
19
|
+
2. **No shared data model changes**: the feature does not depend on a schema migration, new database table, or new shared utility introduced by another feature in the same batch. If feature A adds a `users.rate_limit_tier` column and feature B reads that column, B depends on A.
|
|
20
|
+
|
|
21
|
+
3. **Spec is complete**: the feature's OpenSpec change is fully approved before the batch runs. Specs that are still being revised during implementation produce inconsistent results.
|
|
22
|
+
|
|
23
|
+
4. **Wave 1 in the dependency DAG**: the feature has no unimplemented prerequisites. A feature with `Prerequisites: #71` cannot run in the same batch as #71 — it must wait for #71 to ship first.
|
|
24
|
+
|
|
25
|
+
When in doubt, run `/sr:product-backlog` to see the dependency ordering before composing your batch.
|
|
26
|
+
|
|
27
|
+
## What's not safe
|
|
28
|
+
|
|
29
|
+
Some combinations look independent but are not:
|
|
30
|
+
|
|
31
|
+
**Two features that both modify the same schema file.** Even if the migrations are logically independent (adding different columns to different tables), they both touch `db/schema.sql` or the migration directory. The merge will conflict or produce an incorrect combined schema.
|
|
32
|
+
|
|
33
|
+
**A feature that requires a utility extracted by another feature in the same batch.** If issue #71 refactors authentication middleware into a shared utility, and issue #85 uses that utility, #85 cannot run in the same batch as #71. At the time #85's Developer runs, the shared utility doesn't exist yet.
|
|
34
|
+
|
|
35
|
+
**Features with a `Prerequisites:` relationship to each other.** If issue #85 has `Prerequisites: #71` in its issue body, the Product Analyst's dependency DAG already captures this. Running them together ignores the declared ordering.
|
|
36
|
+
|
|
37
|
+
**Features where the spec says "depends on the outcome of X".** This phrasing signals a runtime dependency that may not be captured in the `Prerequisites:` field. Treat it as an explicit exclusion from the current batch.
|
|
38
|
+
|
|
39
|
+
## Reading the dependency DAG
|
|
40
|
+
|
|
41
|
+
Run `/sr:product-backlog` before composing any parallel batch. The output includes a prioritized backlog table with dependency metadata. Wave 1 features — those with no unimplemented prerequisites — are your safe parallel batch candidates.
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
/sr:product-backlog
|
|
45
|
+
|
|
46
|
+
┌─ API ──────────────────────────────────────────┐
|
|
47
|
+
│ # Issue Score Effort Description │
|
|
48
|
+
│ 1 #85 12/15 Medium Health check endpoint │
|
|
49
|
+
│ 2 #71 10/15 Low Rate limiting │
|
|
50
|
+
│ 3 #63 8/15 High GraphQL migration │
|
|
51
|
+
└─────────────────────────────────────────────────┘
|
|
52
|
+
|
|
53
|
+
Top 3 for next sprint:
|
|
54
|
+
1. #71 — Rate limiting (score/effort: 3.33)
|
|
55
|
+
2. #85 — Health check (score/effort: 2.40)
|
|
56
|
+
3. #63 — GraphQL (score/effort: 0.53)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The backlog output shows effort and score, but it does not explicitly label Wave 1 vs. Wave 2. You determine Wave 1 by reading the `Prerequisites:` field on each issue. Any issue whose prerequisites are all already merged is a Wave 1 candidate.
|
|
60
|
+
|
|
61
|
+
Use the Product Analyst's reasoning section (shown when running with verbose output) to confirm the dependency ordering before batching.
|
|
62
|
+
|
|
63
|
+
## Practical example
|
|
64
|
+
|
|
65
|
+
Three issues are in your sprint: #85 (health check endpoint), #71 (rate limiting middleware), and #63 (GraphQL migration).
|
|
66
|
+
|
|
67
|
+
Reading the issue bodies:
|
|
68
|
+
- #85 has `Prerequisites: #71` — the health check reads the rate limit status, so it needs the middleware to exist first.
|
|
69
|
+
- #71 has no prerequisites.
|
|
70
|
+
- #63 has no prerequisites.
|
|
71
|
+
|
|
72
|
+
#71 and #63 are independent of each other and have no prerequisites. They are Wave 1. Run them in parallel:
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
/sr:batch-implement #71, #63
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Both pipelines run concurrently. Each produces a PR. After both PRs are merged, #85 is unblocked. Run it alone:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
/sr:implement #85
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Attempting to include #85 in the first batch would have caused the Developer for #85 to run without the rate limiting middleware in place, producing code that imports a module that doesn't exist yet.
|
|
85
|
+
|
|
86
|
+
## When auto-merge fails
|
|
87
|
+
|
|
88
|
+
After all worktree pipelines complete, specrails attempts to merge each feature branch into the base. When the merge succeeds automatically, each feature gets its own PR. When it fails, specrails surfaces the conflict and stops.
|
|
89
|
+
|
|
90
|
+
**Symptom**: merge conflict reported in the worktree merge step, pipeline exits before PR creation for one or more features.
|
|
91
|
+
|
|
92
|
+
**Cause**: two features edited the same region of the same file. This happens most often in configuration files, shared utilities, or index files that aggregate exports.
|
|
93
|
+
|
|
94
|
+
**Recovery**:
|
|
95
|
+
1. Note which features conflicted.
|
|
96
|
+
2. Pick one feature's branch as the base. Merge it into the base branch first (it will succeed — the conflict is between the two feature branches, not between either and base).
|
|
97
|
+
3. For the conflicting feature branch, manually resolve the conflict by merging the base branch into it.
|
|
98
|
+
4. Once the conflict is resolved, the Developer can rerun from Phase 5 (PR creation) to create the PR with the resolved branch.
|
|
99
|
+
|
|
100
|
+
**Prevention**: run the safe parallelization criteria before batching. Index files and configuration files are common conflict sources — if two features both register something in the same registry or config object, consider whether they should be sequenced instead.
|
|
101
|
+
|
|
102
|
+
## Patterns & Anti-patterns
|
|
103
|
+
|
|
104
|
+
| Pattern | Why it works |
|
|
105
|
+
|---------|-------------|
|
|
106
|
+
| Run `/sr:product-backlog` before composing a batch | Surfaces the dependency DAG so you batch only Wave 1 features |
|
|
107
|
+
| Keep batches to 2–4 features | Smaller batches reduce conflict surface area and keep the merge step fast |
|
|
108
|
+
| Ensure all specs are approved before starting the batch | Prevents mid-batch spec revisions that invalidate a running pipeline |
|
|
109
|
+
| Sequence database migration features before features that consume the schema | Eliminates the most common class of parallel dev failures |
|
|
110
|
+
|
|
111
|
+
| Anti-pattern | Why it fails |
|
|
112
|
+
|-------------|-------------|
|
|
113
|
+
| Batching features that share a configuration or registry file | Almost guarantees a merge conflict in a file that both features modified |
|
|
114
|
+
| Including a feature whose prerequisite is also in the batch | The dependent feature's Developer runs before the prerequisite exists, producing broken imports and missing types |
|
|
115
|
+
| Running a batch before all specs are written | An incomplete spec causes the Architect to make assumptions; you may get a PR for a feature that was redefined mid-run |
|
|
116
|
+
| Treating all "unrelated" features as parallelizable | "Unrelated" at the product level can still mean "touching the same file" at the code level — verify file isolation, not just feature isolation |
|
|
117
|
+
|
|
118
|
+
## What's next?
|
|
119
|
+
|
|
120
|
+
- [Workflows & Commands](workflows.md) — full reference for `/sr:batch-implement`, `/sr:implement`, and `/sr:product-backlog`
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
[← Product Discovery](playbook-product-discovery.md) · [OSS Maintainer Workflow →](playbook-oss-maintainer.md)
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Product Discovery
|
|
2
|
+
|
|
3
|
+
> For OSS maintainers using specrails with OpenSpec who want every implementation to land right the first time.
|
|
4
|
+
|
|
5
|
+
## Why spec quality determines implementation quality
|
|
6
|
+
|
|
7
|
+
The Architect agent reads your spec before writing a single task. It has no other source of truth. If your proposal is ambiguous, the design it produces will be ambiguous. If the design is ambiguous, the Developer will fill the gaps with assumptions — and those assumptions may not match your intent.
|
|
8
|
+
|
|
9
|
+
The pipeline is only as good as the spec that enters it. A vague feature request produces code that technically compiles and tests pass, but misses the product intent entirely. A precise, well-structured spec produces a design artifact that the Developer can follow without guessing.
|
|
10
|
+
|
|
11
|
+
This isn't unique to AI agents. The same dynamic plays out in human teams: the clearer the ticket, the fewer the back-and-forths. With specrails, the cost of ambiguity is higher because there is no back-and-forth — the pipeline runs to completion and surfaces a PR. At that point, the cost to correct a wrong assumption is much higher than the cost to write a better spec upfront.
|
|
12
|
+
|
|
13
|
+
## Anatomy of a good OpenSpec proposal
|
|
14
|
+
|
|
15
|
+
OpenSpec proposals have four required fields: What, Why, Non-goals, and Success criteria. Each field should be concrete enough that a reader who has never touched your codebase understands the full scope of the change.
|
|
16
|
+
|
|
17
|
+
**Vague proposal:**
|
|
18
|
+
```
|
|
19
|
+
Add a dashboard page showing user stats.
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
This leaves every significant question unanswered: which stats, which users, what layout, what data source, what defines "done"?
|
|
23
|
+
|
|
24
|
+
**Good proposal:**
|
|
25
|
+
```
|
|
26
|
+
What: Add a /dashboard route that renders a stats panel for the authenticated user.
|
|
27
|
+
The panel shows: total API calls in the last 30 days, current rate limit window status,
|
|
28
|
+
and top 3 endpoints by call volume. Data comes from the existing /api/usage endpoint.
|
|
29
|
+
|
|
30
|
+
Why: OSS users need to self-diagnose rate limit issues without opening a support ticket.
|
|
31
|
+
The Product Analyst scored this High on the Developer persona (pain: "I don't know when
|
|
32
|
+
I'm about to hit a rate limit").
|
|
33
|
+
|
|
34
|
+
Non-goals: Historical charts, export functionality, and admin views are out of scope.
|
|
35
|
+
This is a read-only display panel.
|
|
36
|
+
|
|
37
|
+
Success criteria: Authenticated user loads /dashboard and sees accurate stats within 2s.
|
|
38
|
+
Unauthenticated user is redirected to /login. All three stat types render correctly
|
|
39
|
+
in a 375px viewport. Zero console errors.
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The difference is not length — it is specificity. The Architect can produce a task breakdown from the good proposal without making a single assumption.
|
|
43
|
+
|
|
44
|
+
## Writing GitHub Issues the Product Analyst can parse
|
|
45
|
+
|
|
46
|
+
The Product Analyst reads your GitHub Issues labeled `product-driven-backlog` to build the dependency DAG and score your backlog. The issue body structure matters.
|
|
47
|
+
|
|
48
|
+
**The `Prerequisites:` field** is how you tell the Product Analyst that one issue depends on another. When you run `/sr:product-backlog`, the dependency DAG is built from these declarations. Issues without prerequisites are Wave 1 candidates — safe to implement in parallel. Issues with prerequisites are scheduled after their dependencies complete.
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
Prerequisites: #71 (rate limiting middleware must exist before we can display rate limit status)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Write this field even when the dependency seems obvious. The Product Analyst reads issues in isolation — it doesn't infer dependencies from context.
|
|
55
|
+
|
|
56
|
+
**VPC-aligned descriptions** help the Product Analyst score your issue accurately. Mention which persona benefits and describe the pain or gain being addressed. "As a developer debugging API integration issues, I need to see my current rate limit window status without making a test request" gives the Product Analyst enough context to score correctly. "Add rate limit display" does not.
|
|
57
|
+
|
|
58
|
+
**Effort labels** (Low / Medium / High) affect priority scoring. The Product Analyst uses the score-to-effort ratio to rank recommendations. A Low-effort feature with a High score ranks above a High-effort feature with the same score. Set realistic effort labels — optimistic labels inflate priority and create scheduling surprises.
|
|
59
|
+
|
|
60
|
+
## Choosing your entry point
|
|
61
|
+
|
|
62
|
+
specrails offers two paths into the OpenSpec pipeline:
|
|
63
|
+
|
|
64
|
+
**`/opsx:ff` (Fast Forward)** generates all artifacts in one pass: proposal, design, tasks, and context bundle. The Architect runs through each artifact without stopping for review. Use this when:
|
|
65
|
+
- You know exactly what you want to build
|
|
66
|
+
- The approach is well-understood and not architecturally novel
|
|
67
|
+
- You'd approve the design without reading it carefully
|
|
68
|
+
|
|
69
|
+
**`/opsx:new` + `/opsx:continue`** creates artifacts one at a time, pausing after each. You review the proposal before the design is written, and the design before tasks are generated. Use this when:
|
|
70
|
+
- Requirements are still being refined
|
|
71
|
+
- The feature touches sensitive architecture areas
|
|
72
|
+
- You want to redirect the design approach before tasks are committed
|
|
73
|
+
- The feature has security or data-model implications worth reviewing before code is written
|
|
74
|
+
|
|
75
|
+
Rule of thumb: if you'd accept the Architect's first draft without edits, use `/opsx:ff`. If you want a checkpoint between "what we're building" and "how we're building it," use the step-by-step path.
|
|
76
|
+
|
|
77
|
+
Once artifacts are complete, `/opsx:apply` hands them to the Developer. After implementation, `/opsx:archive` closes the change.
|
|
78
|
+
|
|
79
|
+
## The context bundle matters
|
|
80
|
+
|
|
81
|
+
The context bundle is the set of files, interfaces, and decisions that the Developer reads before writing code. A thin context bundle forces the Developer to explore the codebase independently — and exploration introduces risk. The Developer may read an outdated version of a file, miss a constraint documented elsewhere, or invent types that conflict with existing ones.
|
|
82
|
+
|
|
83
|
+
A good context bundle includes:
|
|
84
|
+
- **Files to read**: specific file paths, not directory globs
|
|
85
|
+
- **Key interfaces**: paste the exact TypeScript interface or API contract, not a link to it
|
|
86
|
+
- **Architectural decisions**: what approach was chosen and why, so the Developer doesn't choose a different approach that conflicts with the rest of the system
|
|
87
|
+
- **Known constraints**: anything that would make the naive implementation wrong (auth requirements, transaction boundaries, rate limits, backward-compatibility rules)
|
|
88
|
+
|
|
89
|
+
The context bundle is generated automatically by `/opsx:ff` and `/opsx:continue`. You can edit it before running `/opsx:apply`. Investing 10 minutes in tightening the context bundle typically saves 30 minutes of review on the resulting PR.
|
|
90
|
+
|
|
91
|
+
## Patterns & Anti-patterns
|
|
92
|
+
|
|
93
|
+
| Pattern | Why it works |
|
|
94
|
+
|---------|-------------|
|
|
95
|
+
| Proposal includes explicit Non-goals | Prevents scope creep during implementation — the Developer doesn't add "nice to have" features that weren't requested |
|
|
96
|
+
| Design artifact describes the approach per layer | Developer has no ambiguity about which files to touch and in what order |
|
|
97
|
+
| Context bundle includes exact TypeScript interfaces | Developer doesn't invent types that conflict with existing ones, reducing type errors and review cycles |
|
|
98
|
+
| Success criteria are binary (pass/fail) | Easier to verify at review time — "redirects to /login when unauthenticated" is verifiable; "handles auth correctly" is not |
|
|
99
|
+
|
|
100
|
+
| Anti-pattern | Why it fails |
|
|
101
|
+
|-------------|-------------|
|
|
102
|
+
| Skipping the design artifact and going straight to tasks | Tasks without design rationale produce code that passes tests but breaks the architecture — the Developer follows the task list without understanding the system intent |
|
|
103
|
+
| Spec written after implementation | The spec becomes documentation, not a contract — the pipeline can't use it to validate the implementation against product intent |
|
|
104
|
+
| Vague acceptance criteria ("looks good", "works correctly") | The Reviewer can't determine done-ness and the Developer can't verify its own output against a clear bar |
|
|
105
|
+
| Missing cross-references in context bundle | Developer reads the wrong version of a file or misses a constraint, producing a PR that requires significant rework |
|
|
106
|
+
|
|
107
|
+
## What's next?
|
|
108
|
+
|
|
109
|
+
- [Core Concepts](concepts.md) — understand the pipeline phases and agent roles
|
|
110
|
+
- [Workflows & Commands](workflows.md) — the full command reference including OpenSpec commands
|
|
111
|
+
- [Customization](customization.md) — adapt the Architect and Developer agents to your project conventions
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
[← Updating](updating.md) · [Parallel Development →](playbook-parallel-dev.md)
|
package/docs/updating.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Updating
|
|
2
|
+
|
|
3
|
+
SpecRails includes an update system that pulls new templates while preserving your customizations.
|
|
4
|
+
|
|
5
|
+
## How updates work
|
|
6
|
+
|
|
7
|
+
The update system uses a **manifest-based approach**:
|
|
8
|
+
|
|
9
|
+
1. During installation, SpecRails generates `.specrails-manifest.json` — a checksum of every installed file
|
|
10
|
+
2. On update, it compares the manifest against current files to detect what you've customized
|
|
11
|
+
3. Customized files are preserved; unchanged files are updated to the latest version
|
|
12
|
+
|
|
13
|
+
## Running an update
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
curl -sL https://raw.githubusercontent.com/fjpulidop/specrails/main/update.sh | bash
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Or from a local clone:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
bash /path/to/specrails/update.sh
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### What happens
|
|
26
|
+
|
|
27
|
+
1. **Backup** — creates `.claude.specrails.backup/` with your current files
|
|
28
|
+
2. **Version check** — compares installed version (`.specrails-version`) with latest
|
|
29
|
+
3. **Update files** — replaces unchanged files, preserves customized ones
|
|
30
|
+
4. **Merge settings** — additively merges `settings.json` (your permissions are kept)
|
|
31
|
+
5. **Update version** — writes new version and manifest
|
|
32
|
+
|
|
33
|
+
If anything fails, the backup is restored automatically.
|
|
34
|
+
|
|
35
|
+
## Selective updates
|
|
36
|
+
|
|
37
|
+
Update only specific components with the `--only` flag:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Update core files (setup command, templates, prompts, skills)
|
|
41
|
+
bash update.sh --only core
|
|
42
|
+
|
|
43
|
+
# Update Pipeline Monitor dashboard
|
|
44
|
+
bash update.sh --only web-manager
|
|
45
|
+
|
|
46
|
+
# Regenerate agents (prompts for confirmation if templates changed)
|
|
47
|
+
bash update.sh --only agents
|
|
48
|
+
|
|
49
|
+
# Full update (default)
|
|
50
|
+
bash update.sh --only all
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## What gets preserved
|
|
54
|
+
|
|
55
|
+
| File type | Behavior |
|
|
56
|
+
|-----------|----------|
|
|
57
|
+
| **Agent prompts** (`.claude/agents/`) | Preserved if customized; updated if unchanged |
|
|
58
|
+
| **Commands** (`.claude/commands/`) | Updated (commands are orchestration, not customized) |
|
|
59
|
+
| **Rules** (`.claude/rules/`) | Preserved if customized |
|
|
60
|
+
| **Settings** (`settings.json`) | Merged additively (your permissions kept, new ones added) |
|
|
61
|
+
| **Agent memory** (`.claude/agent-memory/`) | Always preserved |
|
|
62
|
+
| **Personas** (`.claude/agents/*.md`) | Always preserved |
|
|
63
|
+
| **Security exemptions** | Always preserved |
|
|
64
|
+
|
|
65
|
+
## Legacy installations
|
|
66
|
+
|
|
67
|
+
If you installed SpecRails before the versioning system (pre-v0.1.0):
|
|
68
|
+
|
|
69
|
+
- The updater detects missing `.specrails-version` and treats it as a legacy install
|
|
70
|
+
- It migrates your installation to the versioned system
|
|
71
|
+
- A manifest is generated from your current files
|
|
72
|
+
- Future updates use the standard manifest comparison
|
|
73
|
+
|
|
74
|
+
## Rolling back
|
|
75
|
+
|
|
76
|
+
If something goes wrong, restore from the automatic backup:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Backups are at .claude.specrails.backup/
|
|
80
|
+
cp -r .claude.specrails.backup/.claude .claude
|
|
81
|
+
cp .claude.specrails.backup/.specrails-version .specrails-version
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## What's next?
|
|
87
|
+
|
|
88
|
+
That's the end of the docs. Here are some useful starting points:
|
|
89
|
+
|
|
90
|
+
- [Getting Started](getting-started.md) — if you haven't installed yet
|
|
91
|
+
- [Workflows & Commands](workflows.md) — to start using the pipeline
|
|
92
|
+
- [Customization](customization.md) — to make SpecRails yours
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
[← Customization](customization.md) · [Back to Docs](README.md)
|