@ssheleg/agent-sync 1.9.0 → 1.10.1

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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,43 @@
1
+ ## v1.10.1
2
+
3
+ The claim tag could not be placed on nearly half a real board, and the lease was granted
4
+ anyway.
5
+
6
+ ### Fixed
7
+
8
+ - **A row that CITES an id no longer defeats that id's claim.** `claimTags` in `cell` mode
9
+ selected every row *containing* the id, so an ordinary board sentence — "closed by
10
+ B-12", "blocked until T-1 ships" — made the id ambiguous and the tag was refused.
11
+ Cross-referencing is what boards do: measured on `sshlg-skills`' own board on
12
+ 2026-08-14, **14 of 41 rows cited others, leaving 19 ids that could never be tagged**.
13
+
14
+ The refusal itself was correct — guessing which row carries a claim is how a claim lands
15
+ on somebody else's work. What was wrong is that `acquire` still returned `won`: the
16
+ lease was granted while the registry silently carried no claim, which is precisely the
17
+ state a claim exists to make visible.
18
+
19
+ A markdown board declares which row is which in its **first cell**. `acquire` now
20
+ narrows to the row whose id cell equals the key, and refuses only when no row's id cell
21
+ matches. Tried *after* the existing marker narrowing, so `release` still trusts the
22
+ marker it actually wrote rather than re-deriving the row.
23
+
24
+ Covered by `check_claim_lands_on_the_row_whose_id_cell_matches()`, which builds a two-row
25
+ board where the second row cites the first, and asserts the tag lands on exactly one row
26
+ and that it is the right one — then that release still restores the file byte for byte.
27
+ Watched failing before the fix: *"acquire wrote no claim — a row citing T-1 defeated the
28
+ selector, and the lease was granted with the registry unmarked"*.
29
+
30
+ ## v1.10.0
31
+
32
+ Following `task-pipeline` v1.53.0, which renamed the artifact root's default from
33
+ `docs/superpowers/` to `docs/evidence/` and made the root resolvable (`paths.artifacts`
34
+ in `pipeline.json`, else an existing `docs/evidence/`, else an existing
35
+ `docs/superpowers/` — **the legacy name stays supported and no run warns about it**).
36
+
37
+ Shipped surfaces name the new default now, which is why this is a minor rather than a
38
+ patch. This project's own records moved with the directory and were not rewritten: a
39
+ brief describes where things were when it was written.
40
+
1
41
  ## v1.9.0
2
42
 
3
43
  ### Changed
@@ -19,7 +19,7 @@
19
19
  "docs/OPEN_QUESTIONS.md",
20
20
  "docs/ROADMAP.md",
21
21
  "docs/DOCMAP.md",
22
- "docs/superpowers/retro.md"
22
+ "docs/evidence/retro.md"
23
23
  ],
24
24
  "claimTags": {
25
25
  "docs/ROADMAP.md": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ssheleg/agent-sync",
3
- "version": "1.9.0",
3
+ "version": "1.10.1",
4
4
  "description": "Let concurrent coding agents share one project without colliding — leases with TTL, race-free id reservation, a run journal and a generated board, over a pluggable knowledge cloud.",
5
5
  "bin": {
6
6
  "agent-sync": "bin/agent-sync.js"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "agent-sync",
3
3
  "displayName": "Agent Sync",
4
- "version": "1.9.0",
4
+ "version": "1.10.1",
5
5
  "description": "Coordination layer for multi-agent repositories — leases with TTL, race-free ID reservation, a run journal, a cross-repo signal feed and a generated board, over a pluggable knowledge cloud.",
6
6
  "author": {
7
7
  "name": "ssheleg",
@@ -4,7 +4,7 @@ description: "Use when several coding agents work one repository at the same tim
4
4
  compatibility: "Requires the task-pipeline skill for its stages (npx sshlg-skills install). Needs python3 3.9+ (stdlib only, HTTP included - nothing to pip install) and bash for the hooks. The knowledge backend is configured per project; with none configured it degrades to git-file leases. Enforcement hooks are Claude Code only - on other agents the same checks run as a self-check."
5
5
  license: MIT
6
6
  metadata:
7
- version: "1.9.0"
7
+ version: "1.10.1"
8
8
  author: ssheleg
9
9
  ---
10
10
 
@@ -108,7 +108,7 @@ since the pipeline's documentation track it is longer than the registers:
108
108
  | the decision register (`docs/DECISIONS.md` or `docs/adr/`) | append-only; a concurrent write loses an entry |
109
109
  | `docs/OPEN_QUESTIONS.md`, `docs/ROADMAP.md` | the same |
110
110
  | **`docs/DOCMAP.md`** | seeded into every project the pipeline touches; holds the registers, the propagation matrix and the ratchet floors. Losing it loses the map |
111
- | **`docs/superpowers/retro.md`** | capped at ten standing instructions, so a concurrent write silently **drops a lesson** instead of conflicting visibly |
111
+ | **`docs/evidence/retro.md`** | capped at ten standing instructions, so a concurrent write silently **drops a lesson** instead of conflicting visibly |
112
112
 
113
113
  The schema keeps `agent-sync.json` to known keys, which is why this reasoning lives
114
114
  here and not as a comment in the config.
@@ -33,7 +33,7 @@ from datetime import datetime, timezone
33
33
  from pathlib import Path
34
34
  from typing import Any
35
35
 
36
- VERSION = "1.9.0"
36
+ VERSION = "1.10.1"
37
37
 
38
38
  CONFIG_PATH = Path(".claude/agent-sync.json")
39
39
  ENV_FILE = Path(".env.agent-sync")
@@ -1668,6 +1668,22 @@ class Sync:
1668
1668
  if len(narrowed) == 1:
1669
1669
  hits = narrowed
1670
1670
 
1671
+ # A board says which row is which in its FIRST cell. Every other match is a
1672
+ # row CITING this id — "closed by B-12", "blocked until T-1 ships" — and boards
1673
+ # cross-reference constantly: on the family's own board 14 rows cited others, so
1674
+ # 19 of 41 ids had two candidate rows and their claim was refused. The refusal
1675
+ # was right; granting the lease anyway was not, because the registry then carries
1676
+ # no claim while `acquire` reports `won`. Tried after the marker so a release
1677
+ # still trusts what it actually wrote.
1678
+ if len(hits) > 1:
1679
+ own = []
1680
+ for i in hits:
1681
+ cells = self._row_cells(lines[i])
1682
+ if cells and cells[0].strip() == key:
1683
+ own.append(i)
1684
+ if len(own) == 1:
1685
+ hits = own
1686
+
1671
1687
  if len(hits) > 1:
1672
1688
  notes.append(f"{rel}: `{key}` appears in {len(hits)} table rows — refusing "
1673
1689
  "to guess which one is the claim. Narrow the pattern or edit by hand")