@uri→@id(plain string, no URI validation)@source→@file(the content being annotated)@prior→@input(what produced the content)
@tagheader — space-separated tags for categorization%markback 2— optional version declaration%scope/%covers— sweep pattern (meaningful absence)@file+ inline content can coexist (file is provenance, content is snapshot)- Sidecar convention simplified to
name.ext.mbonly
- LLM workflow layer (
llm.py,workflow.py) — not core to Markback httpxdependencyconfig.py/python-dotenvdependency /--initcommand — not core to Markback- RFC 3986 URI validation on
@id - E003 (malformed URI) no longer emitted
- E005 (content with @source) no longer emitted — coexistence is valid
.label.txt/.feedback.txtas primary sidecar convention (kept as V1 legacy in discovery)
SourceRef→FileRef(alias preserved)Recordfields:uri→id,source→file,prior→input, addedtags- New
write()/append()/write_string()functions - New
normalize()function - New
discover_sidecars()function ParseResultgainsscope,covers,version,covered_files()- V1 compat aliases preserved for all renamed functions
Same state-machine approach as V1. Now also handles:
- File-level
%headers (parsed before records, must be at top of file) - V1 header mapping (detected by keyword, mapped with W010 warning)
@tagwith whitespace splitting and merge across multiple lines
The parser transparently reads V1 files:
@uri→ mapped torecord.id@source→ mapped torecord.file@prior→ mapped torecord.input@source ... <<<compact → handled alongside@file ... <<<- Each V1 header emits W010 warning
%scope + %covers enable "meaningful absence":
%scopedeclares what issues are being checked%coversdeclares the complete file set under review- Files matching
%coverswith no record are implicitly clean for all scope items ParseResult.covered_files()resolves the glob for programmatic access
V1 had 5+ writer functions. V2 has:
write()— write records to a file (auto-format)append()— add a record to existing filewrite_string()— write records to stringnormalize()— canonical rewrite All V1 functions preserved as aliases.
V2: name.ext.mb (append .mb to the full filename)
V1 legacy: .label.txt, .feedback.txt still discovered for backward compat
- Parser tests cover V2 format, V1 backward compat, file-level headers, tags, sweep pattern
- Writer tests cover canonical output, version headers, scope/covers, round-trip
- Linter tests verify all error/warning codes with V2 semantics
- Type tests verify FileRef, Record with new fields, V1 compat aliases
All fixtures updated to V2 format. Error fixtures updated to reflect V2 semantics (e.g., content_with_source is now valid).