docs: specify the bioassert generate command#59
Merged
Conversation
Add specs/generate.md, the design for a `bioassert generate <file>` command that inspects a file and composes a set of default assertions from its extension and current properties, writing them to <file>.assertions.txt. Design: per-family suggestion providers (file, delimited, bam, fasta) each contribute optional structured suggestions, an orchestrator accumulates them broadest-first and renders an assertions file grouped by metric provider (first metric segment) with # comment headers. Counts are pinned with eq; magnitudes use a +/- 50% band. Covers the data model, provider trait, CLI wiring, edge cases, and a unit + integration test plan. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new design specification document describing the planned bioassert generate <file> command, including its data model, provider/orchestrator architecture, CLI shape, and a proposed test plan. This fits into the codebase’s existing “specs/” design-doc set (alongside existing BAM/FASTA/etc specs) and is intended to guide a follow-up implementation PR.
Changes:
- Introduces
specs/generate.md, specifying thebioassert generatecommand behavior and output format. - Documents a provider-based suggestion pipeline, output grouping, and default assertion heuristics (including +/-50% “band” rules).
- Proposes CLI flags, wiring points, and unit/integration test coverage for the future implementation.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+23
to
+26
| - `Value::Display` (`src/core/values/value.rs`) already renders the way an assertions file needs: | ||
| `BytesValue` renders like `1.00MB` (binary, 1024-based), `IntegerValue` renders as a plain number | ||
| with no `K`/`M` suffix, `BooleanValue` renders `true`/`false`, `StringValue` renders verbatim. It is | ||
| the single rendering path and is reused so generated values round-trip through the parser. |
Comment on lines
+27
to
+29
| - `Comparator::Display` (`src/core/comparisons/comparator.rs`) renders SYMBOLS (`>=`, `==`), but an | ||
| assertions file needs the KEYWORD form (`gte`, `eq`). The two must not be confused. Suggestions store | ||
| the comparator as the keyword, not as the `Comparator` enum, so the symbol form can never leak. |
Comment on lines
+50
to
+52
| **The comparator is stored as a keyword, the value pre-rendered.** A suggestion carries | ||
| `comparator: &'static str` (one of `eq`, `gte`, `lte`) rather than the `Comparator` enum, because the | ||
| enum's `Display` renders symbols and an assertions file needs keywords. The set of comparators a |
Comment on lines
+42
to
+45
| - An output line is the assertion syntax `resource metric comparator value`, optionally followed by | ||
| ` # comment`. The resource is the file path as given. A path containing whitespace is single-quoted | ||
| so it round-trips through the grammar, the same rule the parser enforces for locators. | ||
| - The `text.*` family is inline-literal only and is not file-backed, so it contributes nothing when the |
Comment on lines
+127
to
+131
| - **Provider order.** An ordered registry `providers()` mirrors the dispatch order in | ||
| `src/engine/executor.rs`, broadest first: `FileProvider`, `DelimitedProvider`, `BamProvider`, | ||
| `FastaProvider`. `FileProvider` handles any existing file; each format provider handles only its | ||
| extensions. This single list is the ordering authority, so generated files and run-time dispatch | ||
| agree on precedence. |
Comment on lines
+92
to
+96
| The generated file is ordinary bioassert assertion syntax with `#` comments. It opens with a two-line | ||
| provenance banner, then one group per contributing provider. Each group is led by a `# <prefix>` header | ||
| and separated from the next by a blank line. Each assertion is `resource metric comparator value`, with | ||
| an optional inline `# comment`. | ||
|
|
|
|
||
| | Provider | Handles | Suggestions | | ||
| |---|---|---| | ||
| | file | any existing file | `file.exists eq true`; `file.size gt 0B` | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds
specs/generate.md, the design specification for a newbioassert generate <file>command. Spec only; implementation is a separate follow-up.bioassert generate a.tsvinspects a file and composes sensible default assertions from its extension and current properties, then writes them to<file>.assertions.txt(the formatbioassert runconsumes) and informs the user. Example for a TSV: file exists, same column count, and rows within +/- 50% of the current row count.Design highlights
Suggestions.text.*is inline-literal only so it contributes nothing for a file path.#comment headers and a provenance banner.eq(columns, fasta records, bam references); magnitudes use a +/- 50% band (gte floor(0.5R),lte ceil(1.5R)); the universal file group stays broad (file.exists eq true,file.size gt 0B).column_count,line_count,read_header,read_records, ...); no executor or dispatch changes.generate <file> [--output FILE] [--force], default output<file>.assertions.txt, refuses to clobber without--force.Covers the data model, provider trait, orchestrator, CLI/binary wiring, edge cases, and a unit + integration (snapshot + round-trip) test plan, in the house spec style.
🤖 Generated with Claude Code