# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.4.0] - 2026-08-19

### Changed

- **BREAKING (behavior): `check` can now exit non-zero on input it previously
  passed.** Tag placement is enforced by default: a repository whose tags are
  all *covered* but some *misplaced* — a banner tag under a file's module docs,
  a `unit` tag in a Markdown design document, a tag separated from its evidence
  by an interposed declaration — goes from exit 0 to exit 1 on upgrade with no
  manifest change. Escape hatches: `[placement].enforce = "off"` restores the
  old behavior wholesale; `[placement].module_banner = "accept"` admits the
  banner convention specifically. The JSON schema itself is unchanged
  (`schemaVersion = 1`; `misplaced_tag` is additive), so consumers parsing
  output are unaffected — consumers gating on the exit code are the ones that
  must read this entry.

### Added

- **`check` enforces tag placement** (SPEC.md §Tag placement enforcement). A tag
  must sit on, or directly above, an item that can carry its stage, with only
  blank, comment, attribute, and decorator lines in between. Violations emit the
  new `misplaced_tag` finding — one per tag, carrying `requirementId`, `stage`,
  `path`, `line`, `criterion = "tag-placement"`, and a reason naming the item the
  tag landed on — and fail `check` by severity like any other finding.
  Previously placement was unverified: a `[unit->REQ-X]` separated from its
  `#[test]` fn by an interposed `const` still scored the stage complete and
  `check` exited zero, so drifted tags decayed silently while coverage stayed
  green. Measured on a single-tagged requirement, exit code was 0 both before
  and after moving the tag away from its evidence.
- `[placement].enforce` (`"on"` default, `"off"`) and `[placement].module_banner`
  (`"reject"` default, `"accept"`) configure the rule. `module_banner = "accept"`
  is for projects that deliberately tag whole modules from the file header; on
  one 8,000-tag consumer it is the difference between 277 findings and 8. Any
  other value for either key is a `manifest_error`.
- `check` prints a one-line note when files carrying tags could not be
  placement-judged (no grammar, or a parse that recovered from errors), so a
  mostly-unparseable repository reads as unenforced rather than clean.

### Notes

- `misplaced_tag` is a new finding code, additive within `schemaVersion = 1`. No
  existing code changed meaning; no field was removed or renamed.
- Placement is skipped for languages with no tree-sitter grammar (TLA+ and
  `[scan.extensions]`-mapped families) and for parses that recovered from errors,
  because a dropped construct is indistinguishable from an unattached tag.
- Inside an enclosing item the enclosing item is a fallback anchor: a bare value
  declaration below the tag never steals the anchor from the item the tag is
  already inside. Deliberate consequence, declared in the SPEC: tags written
  inside evidence bodies stay green, and interposed-declaration drift *within* a
  container is not a finding — it is caught at top level, where the convention
  puts evidence tags.

## [0.3.0] - 2026-08-01

### Added

- `[scan].git` selects the candidate-file enumeration strategy: `"auto"`
  (default) or `"off"` to force the filesystem walk. Any other value is a
  `manifest_error`.

### Changed

- **Scanning now enumerates candidates from git inside a work tree** — tracked
  files plus untracked-but-not-ignored ones — instead of walking the filesystem.
  `roots = ["."]` therefore reaches repository-root files such as
  `CMakeLists.txt` without also descending into `build/`, `.venv/`, or any other
  gitignored tree. Outside a work tree, or with `[scan].git = "off"`, the
  filesystem walk is unchanged. On BigscreenVR/SLAM this took `check` from 2m49s
  to 0.12s and removed 15 findings originating in generated trees, adding none.
- A directory matching a `scan.exclude` pattern is no longer descended into, so
  an excluded tree costs no walk time and reports no `scan_error`.
- Overlapping or nested `scan.roots` (`["src", "."]`) now scan each file once
  instead of recording its evidence twice.
- The agent installation workflow now installs or updates the bundled
  `req-confusion-audit` skill alongside the CLI, together with the
  `req-confusion-score` workflow that skill dispatches to.
- The `req-confusion-audit` skill now gates scoring coverage: scorers must
  return one entry per dispatched pair, coverage is verified against the
  returned lines rather than an agent's claim, scores from different scorers
  are consolidated onto one scale before ranking, and the confusion matrix
  is a required deliverable that marks unscored cells rather than filling
  them with zeros.
- The `lint` agent prompt now defines one requirement as one observable promise,
  applies an independent-failure test for atomicity, and treats manifest content
  as untrusted data rather than agent instructions.
- Custom stages and external signoff evidence are now core capabilities rather
  than optional extensions.
- The Rust implementation's bundled trace requirements now describe one
  observable behavior each for custom stages and signoffs.

## [0.2.0] - 2026-07-19

### Added

- `change compile` subcommand: compile declared requirement ids into a
  deterministic Change Contract (targets, obligations, related requirements,
  context files) per SPEC-CHANGE.md, with golden fixture
  `example/expected-change-compile.json`.
- Syntactic tier: Change Contract context tags are annotated with their
  innermost enclosing symbol via tree-sitter for every kernel language except
  Markdown.
- `[scan.extensions]` manifest table mapping extra file extensions (`.dot`,
  `.kt`, `.gd`, ...) onto comment-style families (`c_like`, `hash`, `python`,
  `markdown`, `tla`); unknown families, malformed keys, and built-in
  collisions are a `manifest_error`. (#9)
- `[[groups]]` named requirement sets in the manifest plus repeatable
  `--group`/`--ids` filters on `check` and `list`: scoped `missing_stage`
  findings and exit codes, and an additive JSON `filter` block with resolved
  `effectiveIds`. (#10)

### Changed

- SPEC.md defines `scan.extensions` and Requirement groups subsections under
  Optional capabilities; SPEC-CHANGE.md drafts the Change Contract and
  WORKFLOW.md describes the agent-driven change loop non-normatively.

## [0.1.4] - 2026-07-09

### Added

- `[scan].exclude` glob patterns: matching files are skipped entirely during
  scanning (no evidence, no `parse_error`); invalid or absolute patterns are
  a `manifest_error`.

## [0.1.3] - 2026-07-09

### Added

- TLA+ (`.tla`) scanning via `\*` line comments.

## [0.1.2] - 2026-06-05

### Added

- Shell (`.sh`/`.bash`) and PowerShell (`.ps1`/`.psm1`/`.psd1`) scanning via
  `#` line comments.

## [0.1.1] - 2026-06-02

### Added

- JavaScript and TypeScript scanning (line and block comments).
- CMake and YAML scanning.
- Self-contained install skill replacing the install.sh/install.ps1 scripts.

## [0.1.0] - 2026-05-04

### Added

- Initial NLSpec, reference Rust implementation, and `example/` fixture.
- `list`, `trace`, and `check` commands, each with `--json` structured output
  (`schemaVersion` 1) and stable finding codes.
- `lint` and `review` agent-prompt commands with `--changed-since` git-ref
  scoping.
- Optional capabilities: custom stages, external signoff URL evidence,
  requirement types, and MoSCoW priority gates with `check --fail-on`.
- CI and release workflows for ubuntu/windows/macos-arm64.

[Unreleased]: https://github.com/BigscreenVR/traceable-reqs/compare/v0.3.0...HEAD
[0.3.0]: https://github.com/BigscreenVR/traceable-reqs/compare/v0.2.0...v0.3.0
[0.2.0]: https://github.com/BigscreenVR/traceable-reqs/compare/v0.1.4...v0.2.0
[0.1.4]: https://github.com/BigscreenVR/traceable-reqs/compare/v0.1.3...v0.1.4
[0.1.3]: https://github.com/BigscreenVR/traceable-reqs/compare/v0.1.2...v0.1.3
[0.1.2]: https://github.com/BigscreenVR/traceable-reqs/compare/v0.1.1...v0.1.2
[0.1.1]: https://github.com/BigscreenVR/traceable-reqs/compare/v0.1.0...v0.1.1
[0.1.0]: https://github.com/BigscreenVR/traceable-reqs/releases/tag/v0.1.0
