markback 0.1.0__py3-none-any.whl → 0.1.1__py3-none-any.whl

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.
markback/linter.py CHANGED
@@ -110,6 +110,33 @@ def lint_source_exists(
110
110
  return diagnostics
111
111
 
112
112
 
113
+ def lint_prior_exists(
114
+ record: Record,
115
+ base_path: Optional[Path],
116
+ record_idx: int,
117
+ ) -> list[Diagnostic]:
118
+ """Check if @prior file exists."""
119
+ diagnostics: list[Diagnostic] = []
120
+
121
+ if record.prior and not record.prior.is_uri:
122
+ try:
123
+ resolved = record.prior.resolve(base_path)
124
+ if not resolved.exists():
125
+ diagnostics.append(Diagnostic(
126
+ file=record._source_file,
127
+ line=record._start_line,
128
+ column=None,
129
+ severity=Severity.WARNING,
130
+ code=WarningCode.W009,
131
+ message=f"@prior file not found: {record.prior}",
132
+ record_index=record_idx,
133
+ ))
134
+ except ValueError:
135
+ pass # URI that can't be resolved to path
136
+
137
+ return diagnostics
138
+
139
+
113
140
  def lint_canonical_format(
114
141
  records: list[Record],
115
142
  original_text: str,
@@ -173,10 +200,11 @@ def lint_string(
173
200
  idx,
174
201
  ))
175
202
 
176
- # Check source file existence
203
+ # Check source and prior file existence
177
204
  if check_sources:
178
205
  base_path = source_file.parent if source_file else None
179
206
  result.diagnostics.extend(lint_source_exists(record, base_path, idx))
207
+ result.diagnostics.extend(lint_prior_exists(record, base_path, idx))
180
208
 
181
209
  # Check canonical format
182
210
  if check_canonical and result.records and not result.has_errors:
markback/parser.py CHANGED
@@ -17,7 +17,7 @@ from .types import (
17
17
 
18
18
 
19
19
  # Known header keywords
20
- KNOWN_HEADERS = {"uri", "source"}
20
+ KNOWN_HEADERS = {"uri", "source", "prior"}
21
21
 
22
22
  # Patterns
23
23
  HEADER_PATTERN = re.compile(r"^@([a-z]+)\s+(.+)$")
@@ -147,6 +147,8 @@ def parse_string(
147
147
  uri = current_headers.get("uri") or pending_uri
148
148
  source_str = current_headers.get("source")
149
149
  source = SourceRef(source_str) if source_str else None
150
+ prior_str = current_headers.get("prior")
151
+ prior = SourceRef(prior_str) if prior_str else None
150
152
 
151
153
  content = None
152
154
  if current_content_lines:
@@ -163,6 +165,7 @@ def parse_string(
163
165
  feedback=feedback,
164
166
  uri=uri,
165
167
  source=source,
168
+ prior=prior,
166
169
  content=content,
167
170
  _source_file=source_file,
168
171
  _start_line=current_start_line,
@@ -239,13 +242,16 @@ def parse_string(
239
242
  line_num,
240
243
  )
241
244
 
242
- # Use any pending @uri from previous line
245
+ # Use any pending @uri from previous line and @prior if present
243
246
  uri = pending_uri or current_headers.get("uri")
247
+ prior_str = current_headers.get("prior")
248
+ prior = SourceRef(prior_str) if prior_str else None
244
249
 
245
250
  record = Record(
246
251
  feedback=feedback or "",
247
252
  uri=uri,
248
253
  source=source,
254
+ prior=prior,
249
255
  content=None,
250
256
  _source_file=source_file,
251
257
  _start_line=current_start_line,
markback/types.py CHANGED
@@ -37,6 +37,7 @@ class WarningCode(Enum):
37
37
  W006 = "W006" # Missing @uri (record has no identifier)
38
38
  W007 = "W007" # Paired feedback file not found
39
39
  W008 = "W008" # Non-canonical formatting detected
40
+ W009 = "W009" # @prior file not found
40
41
 
41
42
 
42
43
  @dataclass
@@ -122,6 +123,7 @@ class Record:
122
123
  feedback: str
123
124
  uri: Optional[str] = None
124
125
  source: Optional[SourceRef] = None
126
+ prior: Optional[SourceRef] = None
125
127
  content: Optional[str] = None
126
128
  metadata: dict = field(default_factory=dict)
127
129
 
@@ -154,6 +156,7 @@ class Record:
154
156
  return {
155
157
  "uri": self.uri,
156
158
  "source": str(self.source) if self.source else None,
159
+ "prior": str(self.prior) if self.prior else None,
157
160
  "content": self.content,
158
161
  "feedback": self.feedback,
159
162
  "metadata": self.metadata,
markback/writer.py CHANGED
@@ -38,15 +38,19 @@ def write_record_canonical(
38
38
  )
39
39
 
40
40
  if use_compact:
41
- # Compact format: @uri on its own line (if present), then @source ... <<<
41
+ # Compact format: @uri on its own line (if present), then @prior, then @source ... <<<
42
42
  if record.uri:
43
43
  lines.append(f"@uri {record.uri}")
44
+ if record.prior:
45
+ lines.append(f"@prior {record.prior}")
44
46
  lines.append(f"@source {record.source} <<< {record.feedback}")
45
47
  else:
46
48
  # Full format
47
- # Headers: @uri first, then @source
49
+ # Headers: @uri first, then @prior, then @source
48
50
  if record.uri:
49
51
  lines.append(f"@uri {record.uri}")
52
+ if record.prior:
53
+ lines.append(f"@prior {record.prior}")
50
54
  if record.source:
51
55
  lines.append(f"@source {record.source}")
52
56
 
@@ -147,6 +151,9 @@ def write_label_file(record: Record) -> str:
147
151
 
148
152
  if record.uri:
149
153
  lines.append(f"@uri {record.uri}")
154
+
155
+ if record.prior:
156
+ lines.append(f"@prior {record.prior}")
150
157
 
151
158
  lines.append(f"<<< {record.feedback}")
152
159
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: markback
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: A compact, human-writable format for storing content paired with feedback/labels
5
5
  Project-URL: Homepage, https://github.com/dandriscoll/markback
6
6
  Project-URL: Repository, https://github.com/dandriscoll/markback
@@ -196,6 +196,16 @@ Second content.
196
196
  @source ./images/003.jpg <<< approved; scene=mountain
197
197
  ```
198
198
 
199
+ ### With Prior Reference
200
+
201
+ Use `@prior` to reference an item that precedes the source (e.g., a prompt that generated an image):
202
+
203
+ ```
204
+ @uri local:generated-001
205
+ @prior ./prompts/sunset-prompt.txt
206
+ @source ./images/generated-sunset.jpg <<< accurate; matches prompt well
207
+ ```
208
+
199
209
  ### Paired Files
200
210
 
201
211
  **content.txt:**
@@ -0,0 +1,14 @@
1
+ markback/__init__.py,sha256=B0-2dpUu5nkbnUI0hPz-x7PHiOl7M-tiRi6s3UCYJFk,1540
2
+ markback/cli.py,sha256=5wMk1OUG7W_voS9DxeFxRJrBTMabEdOK_s_o3Irxuu0,13639
3
+ markback/config.py,sha256=eTVhb7UwDER9FRYo8QUAvneLHSqXD2ZtLUgtBtnljUs,5455
4
+ markback/linter.py,sha256=JfhQV9R6K6Rm1I0Tu9ugU5d19MegQ9eZHlI_wyjk55k,9653
5
+ markback/llm.py,sha256=ON5_2C6v4KIk7_aIceulfWjEEI6hmallaPlLv-1-s_o,4692
6
+ markback/parser.py,sha256=P7GRjlwhy8j6Tnub7XAqILtZ4pFdkfdHhB-aIjLVRYU,18881
7
+ markback/types.py,sha256=6-aO1tkn9JZ1B47IFi7N9lf5_V8Y0LFrNQMoPgkp8Kc,8707
8
+ markback/workflow.py,sha256=zC1RUm1i1wgiciFDqUilJKJ0-bgInvctxhQ0h5WSdoQ,10485
9
+ markback/writer.py,sha256=3-LeupyuruGv4WZH9pV65hU4YDKuC5HgIIZ8YZ2SZnM,7896
10
+ markback-0.1.1.dist-info/METADATA,sha256=KsRmvJPyZLbvHGcNIeMiemLDTH2z2znLrs9U1SPCUVE,5133
11
+ markback-0.1.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
12
+ markback-0.1.1.dist-info/entry_points.txt,sha256=Bc9aXvtlPxVPuOJ9BWGngAVrkx5dMvRgujjVzXC-V5U,46
13
+ markback-0.1.1.dist-info/licenses/LICENSE,sha256=lLK1n13C_CXb0M10O-6itEIDY6dsXKutZYQH-09n6s0,1068
14
+ markback-0.1.1.dist-info/RECORD,,
@@ -1,14 +0,0 @@
1
- markback/__init__.py,sha256=B0-2dpUu5nkbnUI0hPz-x7PHiOl7M-tiRi6s3UCYJFk,1540
2
- markback/cli.py,sha256=5wMk1OUG7W_voS9DxeFxRJrBTMabEdOK_s_o3Irxuu0,13639
3
- markback/config.py,sha256=eTVhb7UwDER9FRYo8QUAvneLHSqXD2ZtLUgtBtnljUs,5455
4
- markback/linter.py,sha256=6jrfngF4PiYFQlDddm09OEmVSSGwacE5YFxMub5mqlA,8707
5
- markback/llm.py,sha256=ON5_2C6v4KIk7_aIceulfWjEEI6hmallaPlLv-1-s_o,4692
6
- markback/parser.py,sha256=5CrLeOWGuiE0_BOK9dJUnLLrJ72KTmucyOQEzR1nDh4,18570
7
- markback/types.py,sha256=rRy41h1ZYYP9lo_FhvP5X5-OlwEM7vzHCw--Sq5L2LA,8564
8
- markback/workflow.py,sha256=zC1RUm1i1wgiciFDqUilJKJ0-bgInvctxhQ0h5WSdoQ,10485
9
- markback/writer.py,sha256=v5KT2o2Ma2I9I4U-r06PgzKyqwQFSsx49Ri5qIsovhY,7645
10
- markback-0.1.0.dist-info/METADATA,sha256=aqRMZiWqsEExkqi_dwSyWtcFb3uhOx2Ol6HbNBU7Ggw,4864
11
- markback-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
12
- markback-0.1.0.dist-info/entry_points.txt,sha256=Bc9aXvtlPxVPuOJ9BWGngAVrkx5dMvRgujjVzXC-V5U,46
13
- markback-0.1.0.dist-info/licenses/LICENSE,sha256=lLK1n13C_CXb0M10O-6itEIDY6dsXKutZYQH-09n6s0,1068
14
- markback-0.1.0.dist-info/RECORD,,