diff --git a/docs/outstanding.md b/docs/outstanding.md index 1bc0473..b6addb2 100644 --- a/docs/outstanding.md +++ b/docs/outstanding.md @@ -320,9 +320,12 @@ fixed before spike S9", because S9 both validates R1 and calibrates what toleran The threshold was never fixed and S9 has not run, so R1 currently has no acceptance criterion at all — there is nothing a test could assert. -Worse, the matrix reports R1 as *covered*. Both of its tags are string literals inside the -traceability tool's own unit tests (`tools/traceability/src/lib.rs`), which the tool scans along with -everything else, because a fixture demonstrating tag extraction is indistinguishable from a tag. +The matrix used to report R1 as *covered*, and what covered it was two string literals: fixtures +inside the traceability tool's own unit tests, which the tool scans along with everything else, +because a fixture demonstrating tag extraction was indistinguishable from a tag. The extractor now +asks where the tag sits — a tag is the first word of a comment, not a string appearing anywhere on a +line — and R1 is untagged again, which is the honest reading while it has no acceptance criterion to +tag anything against. NFR-OPS-1 is covered the same way, from a tag on `compute_coverage` — and no rotating, size-capped on-disk log exists; logging goes to stderr and logcat. These are two of the cases [CONTRIBUTING.md](../CONTRIBUTING.md) already warns about, now named. diff --git a/tools/traceability/src/lib.rs b/tools/traceability/src/lib.rs index bbc8e29..b3ee4da 100644 --- a/tools/traceability/src/lib.rs +++ b/tools/traceability/src/lib.rs @@ -19,6 +19,20 @@ //! count as the numerator is precisely what lets a ratio exceed 100%, since //! a tag naming a deleted requirement would count as covered. Such tags are //! reported as orphans instead. +//! +//! # And why the extractor is fussy about where a tag sits +//! +//! A third rule, learned the same way. `SOURCE_ROOTS` includes `tools`, so this +//! crate scans itself, and the fixtures below demonstrating tag extraction were +//! read as tags: R1 — cross-platform output within a bounded tolerance — was +//! reported implemented on the strength of two string literals in a unit test. +//! +//! 3. **A tag is a comment whose first word is `TRACES:`**, not a line in which +//! the string appears. This is a rule about position +//! rather than about string literals, because `schema.rs` writes real tags +//! inside string literals — the SQL it embeds is commented with `--` — and +//! an extractor that refused those would lose six genuine tags to save two +//! false ones. use std::collections::{BTreeMap, BTreeSet}; use std::path::{Path, PathBuf}; @@ -182,16 +196,43 @@ pub fn is_requirement(id: &str) -> bool { REQUIREMENT_TYPES.contains(&type_of(id)) } +/// Comment openers a tag may be introduced by. +/// +/// `--` is here for the SQL embedded in `schema.rs`, which carries real tags +/// inside Rust string literals; `#` for YAML; `*` for the continuation lines of +/// a block comment. +const COMMENT_OPENERS: &[&str] = &["///", "//!", "//", "