@ssheleg/agent-sync 1.11.0 → 1.12.0

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,66 @@
1
+ ## v1.12.0 — 246 kB of someone else's bytecode, in every install
2
+
3
+ **The published tarball carried a `.pyc` both ignore files were written to exclude.**
4
+ `@ssheleg/agent-sync@1.11.1` ships
5
+ `plugins/agent-sync/skills/agent-sync/scripts/__pycache__/agent_sync.cpython-312.pyc` —
6
+ **245.8 kB against 175.7 kB of source beside it**, 40% of the tarball, compiled by
7
+ whatever interpreter the publisher happened to be running. Verified by unpacking the
8
+ published artefact, not by reading the manifest.
9
+
10
+ `.gitignore:3-4` and `.npmignore:1-2` both exclude `__pycache__/` and `*.pyc`. **Neither
11
+ is consulted once `files` names a directory** — the whitelist wins, so the intent was
12
+ recorded twice and enforced nowhere. `files` now carries `!plugins/**/__pycache__` and
13
+ `!plugins/**/*.pyc`, and the packed result drops from **231.5 kB / 28 files to
14
+ 125.8 kB / 27**.
15
+
16
+ **A filesystem walk would not have caught this**, which is why the new check asks npm.
17
+ `check_the_tarball_carries_no_bytecode()` reads `npm pack --dry-run --json` — the
18
+ packer's own answer to *what would ship* — and fails on any `.pyc` or `__pycache__` in
19
+ it. Where npm is absent it discloses rather than passing: a check that cannot look must
20
+ never read as one that looked. Watched failing against the exact state that shipped, and
21
+ added to `--self-test`, now **38 fixtures**.
22
+
23
+ ### Fixed — three documents that told the reader something untrue
24
+
25
+ - **`references/hooks.md` said the hooks are removed by editing `.claude/settings.json`.**
26
+ Nothing here ever writes a `hooks` block there, and Claude Code has no per-hook disable
27
+ for a hook a plugin ships. A user who wanted them gone edited a file with no such block
28
+ and concluded it had worked, while the SessionStart hook kept speaking in every session.
29
+ The two real levers are named now — `enabledPlugins[…] = false` or `plugin uninstall` —
30
+ plus the fact that every hook already self-disables in a project with no
31
+ `.claude/agent-sync.json`.
32
+ - **`CONTRIBUTING.md` said five version surfaces move together; the validator enforces
33
+ six.** The missing one is `VERSION` in `scripts/agent_sync.py`, and it is exactly what
34
+ forced the 1.11.1 patch: a bump driver written from that page moved four of six and CI
35
+ refused the tag. It is the constant `status` prints into every session, so its drift is
36
+ invisible in the manifests and loud in the banner.
37
+ - **`CONTRIBUTING.md` said the self-test injects five defects; it injected thirty-seven.**
38
+ The count is read off the run's own last line now. The number is the whole claim — a
39
+ contributor who reads *five* will not think to add a fixture for the sixth thing they
40
+ change.
41
+
42
+ Found by the nine-repository audit of 2026-08-16 (umbrella `B-72`; the three documents
43
+ are `F-agent-sync-05`, `-08` and `-11`).
44
+
45
+ ## v1.11.1 — the gate can see an invariant it breaks elsewhere
46
+
47
+ **This gate can now see an invariant it breaks one repository away.** The family umbrella
48
+ routes work by matching a prompt against a table in `lib/triggers.js`, and every trigger
49
+ there must be a word this skill's own `description` advertises. Nothing here knew that
50
+ table existed. On 2026-08-16 `sheleg-design` 1.37.0 shipped green having dropped a phrase
51
+ that was still a live trigger, the umbrella found out minutes after the tag, and it cost a
52
+ patch release — because the member releases FIRST and the umbrella re-pins after.
53
+
54
+ `test/validate.py` now asks the umbrella's own checker (`test/advertised_check.js`), which
55
+ reads the module the hook itself calls. **No copy of the table lives here**, so there is
56
+ nothing to drift. With no umbrella above this checkout — a standalone clone, and CI — it
57
+ discloses rather than passing, because a check that cannot look must never read as one
58
+ that looked.
59
+
60
+ Watched refusing a real drop before shipping: every one of the seven members carrying
61
+ routed triggers had one of its own advertised phrases removed and every one of them failed
62
+ its own gate.
63
+
1
64
  ## v1.11.0 — releasing stops rewinding a cell, and a register with no pattern says so
2
65
 
3
66
  Two more defects in the same afternoon that produced v1.10.1, both from using this tool
package/package.json CHANGED
@@ -1,13 +1,15 @@
1
1
  {
2
2
  "name": "@ssheleg/agent-sync",
3
- "version": "1.11.0",
4
- "description": "Let concurrent coding agents share one project without colliding \u2014 leases with TTL, race-free id reservation, a run journal and a generated board, over a pluggable knowledge cloud.",
3
+ "version": "1.12.0",
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"
7
7
  },
8
8
  "files": [
9
9
  "bin/",
10
10
  "plugins/",
11
+ "!plugins/**/__pycache__",
12
+ "!plugins/**/*.pyc",
11
13
  "agent-sync.schema.json",
12
14
  "agent-sync.example.json",
13
15
  "README.md",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "agent-sync",
3
3
  "displayName": "Agent Sync",
4
- "version": "1.11.0",
4
+ "version": "1.12.0",
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.11.0"
7
+ version: "1.12.0"
8
8
  author: ssheleg
9
9
  ---
10
10
 
@@ -103,6 +103,18 @@ echo '{"tool_name":"Edit","tool_input":{"file_path":"docs/DECISIONS.md"},"cwd":"
103
103
 
104
104
  ## Removing them
105
105
 
106
- Delete the `hooks` block from the project's `.claude/settings.json`. The skill keeps
107
- working every guard is also available as a command, and the board simply records
108
- runs as `ungated` from then on.
106
+ **Not** by editing `.claude/settings.json` nothing here ever writes a `hooks`
107
+ block there, and Claude Code has no per-hook disable for a hook a plugin ships. A
108
+ reader who follows that instruction edits a file with no such block and concludes
109
+ the removal worked while every hook keeps firing.
110
+
111
+ Two levers actually work:
112
+
113
+ - `enabledPlugins["agent-sync@agent-sync"] = false` in `~/.claude/settings.json` —
114
+ enablement is the only switch a plugin hook has; or
115
+ - `claude plugin uninstall agent-sync@agent-sync`.
116
+
117
+ And one you usually do not need: every hook already self-disables in a project with
118
+ no `.claude/agent-sync.json` (`hooks/_lib.sh`), so a repository that never opted in
119
+ is not paying for them. The skill keeps working either way — every guard is also
120
+ available as a command, and the board simply records runs as `ungated` from then on.
@@ -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.11.0"
36
+ VERSION = "1.12.0"
37
37
 
38
38
  CONFIG_PATH = Path(".claude/agent-sync.json")
39
39
  ENV_FILE = Path(".env.agent-sync")