task-pipeline-skill 1.3.2 → 1.4.3

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,5 +1,64 @@
1
1
  # Changelog
2
2
 
3
+ ## v1.4.3 — 2026-07-30
4
+
5
+ ### Fixed
6
+ - **`argument-hint` in the slash command was unquoted.** In YAML a bare
7
+ `[a | b]` is a flow sequence, not a string, so the hint parsed as a *list*.
8
+ Found by `claude plugin validate --strict`, the upstream schema checker, which
9
+ now runs in CI on both this plugin and its marketplace manifest.
10
+ - **`homepage` and `repository` sat at the top level of `marketplace.json`,
11
+ where Claude Code does not recognize them.** They are plugin-entry fields;
12
+ moved there, so the values reach the plugin listing instead of being ignored.
13
+
14
+ ## v1.4.2 — 2026-07-30
15
+
16
+ ### Fixed
17
+ - **`pipeline.schema.json` identified itself with a URL that 404s.** The `$id`
18
+ read `https://github.com/ssheleg/task-pipeline/pipeline.schema.json` — a path
19
+ that has never existed (no `blob/main`, wrong depth). This file is installed
20
+ into `~/.claude/skills/task-pipeline/`, so every install carried a schema
21
+ whose declared identity could not be fetched by anything resolving it. Now the
22
+ raw URL that actually serves the file, matching `agent-sync`'s convention.
23
+
24
+ ### Changed
25
+ - `license: MIT` declared in the `marketplace.json` plugin entry and in the
26
+ skill's front matter — the `LICENSE` file was invisible to both surfaces.
27
+
28
+ ## v1.4.1 — 2026-07-30
29
+
30
+ ### Changed
31
+ - `agent-sync` moved to **`ssheleg/agent-sync`**. The three places this skill
32
+ links to it — `SKILL.md`, `references/stages.md`, `references/acceptance.md` —
33
+ now point at the new owner rather than relying on GitHub's redirect.
34
+
35
+ ## v1.4.0 — 2026-07-29
36
+
37
+ ### `references/learned.md` — fourteen rules earned by failure, each with its incident
38
+
39
+ Taught to the pipeline by a real build: a 229-decision specification across four repositories with
40
+ several agents working at once. Every rule names the failure that produced it, because a rule with
41
+ no incident behind it is somebody's preference and gets argued with at the worst moment.
42
+
43
+ The ones that cost the most, now gate criteria rather than advice:
44
+
45
+ - **A gate's exit code is part of its output.** One printed `FAIL` and returned `0`; CI had been
46
+ green over it for an unknown period.
47
+ - **Doubt the probe first.** Five probes failed before any check did — four times out of five the
48
+ planted defect was never planted, and the silence read as a passing check.
49
+ - **Absence needs its own check.** Comparing documents finds contradictions, and a contradiction
50
+ needs two sides; a whole missing subsystem has one. Only the reverse direction of a computed
51
+ mapping found it.
52
+ - **Tests create what they assert on.** A test read another test file's leftovers, so it passed on a
53
+ warm database and failed on the cold one every new developer has.
54
+ - **A generator seeds green** · **local infrastructure does not publish the host's default ports** ·
55
+ **compute rather than restate** · **sweep the class, not the finding** · **ratchet, never TODO**.
56
+
57
+ Wired into stages 5, 6, 9 and 10 as gate criteria, not as reading. Two lessons are deliberately kept
58
+ OUT of the table, as review questions — *is this the right citation* and *did this number come from
59
+ the contract or from prose about it* — because a rule that pretends to be enforced and is not is the
60
+ same failure as the gate that printed `FAIL` and exited `0`.
61
+
3
62
  ## v1.3.2 — 2026-07-29
4
63
 
5
64
  **The 26 negative self-tests could not be run anywhere except CI** — which meant
package/README.md CHANGED
@@ -490,6 +490,19 @@ command into `~/.claude/commands/`; idempotent — rerun skips existing installs
490
490
 
491
491
  ### Updating
492
492
 
493
+ **The family updates as one package** — a bundle with one member current and the rest stale is a
494
+ combination nobody tested:
495
+
496
+ ```bash
497
+ npx sshlg-skills update # installed but behind — updates everything
498
+ npx sshlg-skills install # nothing installed yet
499
+ npx --yes sshlg-skills@latest list # what the current release of each member is
500
+ ```
501
+
502
+ Restart your agent afterwards: skills and hooks load at session start.
503
+
504
+ Per-channel, when you are updating this one member only:
505
+
493
506
  Pick **one** channel per agent — running the plugin and the plain/skills-CLI copy on
494
507
  the same Claude Code install yields a duplicate, shadowing skill.
495
508
 
@@ -551,13 +564,19 @@ Built by ssheleg — [sshlg.me](https://sshlg.me)
551
564
  - Telegram — [@sshlg](https://t.me/sshlg)
552
565
 
553
566
  Part of the [ssheleg skill family](https://github.com/ssheleg/sshlg-skills):
554
- `super-ux`, `task-pipeline`, `make-skill`, `sheleg-design`, `seo-aeo-audit`.
555
- One command installs all five for every agent you use:
567
+ `super-ux`, `task-pipeline`, `agent-sync`, `make-skill`, `sheleg-design`, `seo-aeo-audit`.
568
+ **The family installs and updates as one package**, for every agent you use — a bundle with one
569
+ member current and the rest stale is a combination nobody tested:
556
570
 
557
571
  ```bash
558
- npx sshlg-skills install
572
+ npx sshlg-skills install # nothing installed yet — the whole family, any agent
573
+ npx sshlg-skills update # installed but behind — updates everything
574
+ npx --yes sshlg-skills@latest list # what the current release of each member is
559
575
  ```
560
576
 
577
+ Restart your agent afterwards: skills and hooks load at session start, so the session that
578
+ updates is not the session that gets the new ones.
579
+
561
580
  ## License
562
581
 
563
582
  MIT © 2026 ssheleg. Third-party portions (the ported stage doctrine) are credited
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "task-pipeline-skill",
3
- "version": "1.3.2",
3
+ "version": "1.4.3",
4
4
  "description": "Full-cycle delivery pipeline for coding agents: a mandatory built-in intake grill, then 10 gated stages (docs, brainstorm+decompose, spec, plan, build, tests, lint/deploy, post-deploy, docs/wiki, acceptance). Every stage's doctrine ships inside the skill — no companion plugin required. This package is the installer CLI.",
5
5
  "bin": {
6
6
  "task-pipeline": "bin/task-pipeline.js"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "task-pipeline",
3
3
  "description": "Runs a substantial task through a mandatory built-in intake grill, then 10 gated stages (docs, brainstorm+decompose, spec, plan, subagent build, tests, lint/deploy, post-deploy, docs/wiki, acceptance). Every stage's doctrine is built into the skill — no companion plugin required — with typed auto/manual gates, a frozen requirement spine that must close with evidence, a loop guard that breaks churn, one provider-agnostic model confirmed up front, and an optional super-ux UX track for user-facing work.",
4
- "version": "1.3.2",
4
+ "version": "1.4.3",
5
5
  "author": {
6
6
  "name": "ssheleg"
7
7
  },
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Run a task through task-pipeline — an intake grill that expands the request, then docs → brainstorm → spec → plan → build → tests → deploy → post-deploy → docs/wiki → acceptance.
3
- argument-hint: <one-line task description>
3
+ argument-hint: "<one-line task description>"
4
4
  ---
5
5
  Use the `task-pipeline` skill to run the task below through all gated stages —
6
6
  **stage 0 intake grill** → docs study → brainstorm → spec → plan → subagent
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  name: task-pipeline
3
3
  description: "Use when running a substantial task through the full end-to-end delivery pipeline — an up-front intake grill that expands the request into a complete brief, then docs study, brainstorm, spec, plan, subagent-driven build, tests, lint/deploy, post-deploy log check, docs/wiki sync and acceptance — as gated stages whose doctrine is built entirely into this skill (no required companion skills). Triggers - 'run this through the pipeline' / 'прогони по конвейеру', 'the full cycle' / 'полный цикл', /task-pipeline, or any substantial feature, fix, or build that should follow the disciplined cycle rather than ad-hoc coding. The intake grill is mandatory - it front-loads every decision, including the per-stage autonomy sweep, so stages 1→10 run without mid-flight questions; recommends super-ux for user-facing work; confirms one model up front (most capable available, never a hardcoded id); reads host-project conventions for deploy/docs/wiki so it stays project-agnostic."
4
+ license: MIT
4
5
  ---
5
6
 
6
7
  # task-pipeline
@@ -189,12 +190,12 @@ capable available — see `references/model-tiering.md`).
189
190
  | 2 | Brainstorm + decompose | built in: [`references/brainstorm.md`](references/brainstorm.md) + **UI detection** + [`references/decomposition.md`](references/decomposition.md) for platforms | design approved; UI verdict recorded; every REQ answered; platform: module map approved | manual |
190
191
  | 3 | Spec | built in: [`references/spec.md`](references/spec.md) — **UI → super-ux chain first** (`/ux` → `ux-foundation` CJM → `ux-flows` screens → `ux-scenarios` → `/ux-lint`), then spec `docs/superpowers/specs/…-design.md` | committed + reviewed; UI: chain validated, linter green, scenarios/`SCR-` traced | manual |
191
192
  | 4 | Plan | built in: [`references/planning.md`](references/planning.md) → `docs/superpowers/plans/…md` | parallel-ready, DoD per task | auto |
192
- | 5 | Dev | built in: [`references/build.md`](references/build.md) (worktree → subagent per task → review loop → integrate) + [`references/tdd.md`](references/tdd.md) | tasks DONE, TDD green per task, branch integrated per the brief | auto |
193
- | 6 | Tests | host test runner + built-in [`references/tdd.md`](references/tdd.md) | full suite green; new/changed code covered | auto |
193
+ | 5 | Dev | built in: [`references/build.md`](references/build.md) (worktree → subagent per task → review loop → integrate) + [`references/tdd.md`](references/tdd.md) | tasks DONE, TDD green per task, branch integrated per the brief; **anything generated passes its own checks, and local infrastructure does not publish the host's default ports** ([`references/learned.md`](references/learned.md)) | auto |
194
+ | 6 | Tests | host test runner + built-in [`references/tdd.md`](references/tdd.md) + [`references/learned.md`](references/learned.md) | full suite green; new/changed code covered; **every new check probed both ways and asserted on its exit code**, and the suite run once against a cold environment | auto |
194
195
  | 7 | Lint + deploy | host lint → deploy per host convention | lint clean + suite green before deploy; deploy needs a go (or the brief's specific standing authorization) | manual |
195
196
  | 8 | Post-deploy | tail deploy logs / health-check | clean boot or honest degradation report | auto |
196
- | 9 | Docs + wiki | host module docs/runbook rules → `wiki-update` ([obsidian-wiki](https://github.com/ar9av/obsidian-wiki), recommended) | every stale row of the stage-0 source ledger updated; docs synced; wiki synced | auto |
197
- | 10 | **Acceptance** | built in: [`references/audit.md`](references/audit.md) (ladder walk) → [`references/acceptance.md`](references/acceptance.md) (coverage table) | ladder walk ran, its absences became REQ rows; every REQ accounted for with evidence from a check seen failing once; ledger has no unresolved row; **in a multi-repository project, every repository is clean, pushed and pointed at** (below); operator signs off | manual |
197
+ | 9 | Docs + wiki | host module docs/runbook rules → `wiki-update` ([obsidian-wiki](https://github.com/ar9av/obsidian-wiki), recommended) | every stale row of the stage-0 source ledger updated; docs synced; wiki synced; **every number computed rather than restated, every named command or file resolvable** ([`references/learned.md`](references/learned.md)) | auto |
198
+ | 10 | **Acceptance** | built in: [`references/audit.md`](references/audit.md) (ladder walk) → [`references/acceptance.md`](references/acceptance.md) (coverage table) | ladder walk ran, its absences became REQ rows; every REQ accounted for with evidence from a check seen failing once; ledger has no unresolved row; **axis rotation recorded** (new findings vs self-inflicted, rule 1 of [`references/learned.md`](references/learned.md)), **every closure verified against the artefact rather than the document describing it**, **each correction swept across its class**, **every deferral a printed ratchet rather than a TODO**; **in a multi-repository project, every repository is clean, pushed and pointed at** (below); operator signs off | manual |
198
199
 
199
200
 
200
201
  ### Stage 10 in a project of several repositories
@@ -213,7 +214,7 @@ git -C <each repo> status --porcelain && git -C <each repo> log @{u}..HEAD --one
213
214
  ```
214
215
 
215
216
  report nothing — for the parent as well as every submodule. Where
216
- [agent-sync](https://github.com/appvillis-com/agent-sync) is installed, `/agent-sync finish` runs
217
+ [agent-sync](https://github.com/ssheleg/agent-sync) is installed, `/agent-sync finish` runs
217
218
  exactly this plus *no lease left held*, and `--gates` adds the project's own gate commands.
218
219
 
219
220
  The fix, when it fails, is two commands and the second is the one that gets forgotten:
@@ -258,6 +259,7 @@ automation is on — `pipeline.schema.json` is the only contract.
258
259
  - `references/grill.md` — the built-in stage-0 grill: loop, domain awareness, autonomy sweep
259
260
  - `references/acceptance.md` — the built-in stage-10 close-out: REQ coverage, evidence, sign-off
260
261
  - `references/audit.md` — cross-cutting: the L0→L7 ladder and its seams (what was never written), axis rotation, ratchets, proven checks
262
+ - `references/learned.md` — cross-cutting: fourteen rules earned by failure on a real multi-repository build, each with the incident behind it, its check and its exit criterion; plus the two that no check can decide
261
263
  - `references/brainstorm.md` — stage 2: design dialogue, approaches, UI detection, hard gate
262
264
  - `references/spec.md` — stage 3: UX track order, the spec contract, self-review, review gate
263
265
  - `references/planning.md` — stage 4: zero-context plan format, parallel groups, no placeholders
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
- "$id": "https://github.com/ssheleg/task-pipeline/pipeline.schema.json",
3
+ "$id": "https://raw.githubusercontent.com/ssheleg/task-pipeline/main/plugins/task-pipeline/skills/task-pipeline/pipeline.schema.json",
4
4
  "title": "task-pipeline config",
5
5
  "description": "Generic contract for a pipeline config. An ordered list of stages; each stage is run by the host project's own skills/agents and guarded by a typed gate. The framework imposes no specific stages, skills, or gate assignments — those are entirely the host project's config. Copy pipeline.example.json and rewrite it to match your project.",
6
6
  "type": "object",
@@ -124,7 +124,7 @@ git -C <each repo> status --porcelain
124
124
  git -C <each repo> log @{u}..HEAD --oneline
125
125
  ```
126
126
 
127
- Where [agent-sync](https://github.com/appvillis-com/agent-sync) is installed,
127
+ Where [agent-sync](https://github.com/ssheleg/agent-sync) is installed,
128
128
  `/agent-sync finish` runs exactly this plus *no lease left held*, and `--gates`
129
129
  adds the project's own gate commands.
130
130
 
@@ -0,0 +1,135 @@
1
+ # Rules earned by failure
2
+
3
+ **One job: the mistakes that cost real time on a real project, each with the check that now catches
4
+ it.** Every rule here names the incident that produced it. A rule with no incident behind it is
5
+ somebody's preference, and it will be argued with at the worst moment.
6
+
7
+ They come from one 229-decision, 72-document specification built across four repositories with
8
+ several agents working at once. Nothing here is hypothetical.
9
+
10
+ **A rule belongs in the table only when it has a check.** Two of the lessons below could not be
11
+ mechanised and are kept out of it deliberately, as review questions — because a rule that pretends
12
+ to be enforced and is not is the same failure as a gate that prints `FAIL` and exits `0`.
13
+
14
+ ---
15
+
16
+ ## The table — trigger · check · exit criterion
17
+
18
+ | # | Rule | Trigger | The check | Exit criterion |
19
+ |---|---|---|---|---|
20
+ | 1 | **Change the axis when it stops paying** | any second review or audit pass | count new findings and self-inflicted ones separately | self-inflicted exceeds new → change the axis, do not "look again more carefully" |
21
+ | 2 | **Absence needs its own check** | any two-layer model — entity/table, screen/frame, task/module, requirement/test | compute the mapping in **both** directions | zero orphans each way, printed |
22
+ | 3 | **Verify closure against the artefact** | closing anything that names a design, a build or a file | open the artefact, not the document describing it | the artefact carries a marker naming what it was last verified against |
23
+ | 4 | **Probe the detector** | every new check, lint rule or assertion | plant the defect → run → assert non-zero; restore → assert zero | both directions observed once, and recorded |
24
+ | 5 | **Doubt the probe first** | a check that stays silent when it should fire | prove the planted defect exists in the text the check actually parses | the probe is shown to have changed what the check reads |
25
+ | 6 | **Sweep the class, not the finding** | any correction | grep the whole corpus for the same shape before closing | the class is gated, or named in the note so the next reader can finish it |
26
+ | 7 | **Ratchet, never TODO** | anything that cannot be fixed now | a named, counted set printed on every run | the number may only fall, and `OK` prints it beside itself |
27
+ | 8 | **Compute, never restate** | any count or cross-reference stated in prose | derive it from the source at check time | the stated number and the computed one are the same object |
28
+ | 9 | **A generator seeds green** | any scaffold, template or code generator | run the generated project's own checks inside the generator's tests | fresh output exits zero |
29
+ | 10 | **Measure a detector before trusting it** | a new heuristic check | run it over the real corpus and count false positives | zero false positives, or the heuristic is replaced by a deterministic rule |
30
+ | 11 | **A gate's exit code is part of its output** | any gate or CI step | run it against a planted defect and assert on `$?` | non-zero, not merely a `FAIL` line on stdout |
31
+ | 12 | **Tests create what they assert on** | any test touching shared state | run the suite against a cold, empty environment | the cold run and the warm run agree |
32
+ | 13 | **Local infrastructure does not fight the host** | any dev compose or service definition | assume the host already runs the defaults | services reachable with the host's own still running |
33
+ | 14 | **A document may not send a reader to something absent** | any instruction naming a command, file or install | resolve it | the gate fails when the target does not exist |
34
+
35
+ ---
36
+
37
+ ## The incidents, so the rules are not abstract
38
+
39
+ **1 · Change the axis.** Seven passes of comparing documents against each other were instrumented.
40
+ Findings per pass: 12, 17, 13, 19 — and *caused by the previous pass*: 5, 9, 10, 4. By the sixth
41
+ pass the method was mostly repairing itself, because each pass edits the corpus the next one reads,
42
+ so the newest text is always the least reviewed. The fix is not more care; it is a different axis.
43
+
44
+ **2 · Absence.** Comparing documents found contradictions for weeks and never found that one
45
+ service had **no key store at all** — a decision made it the encryptor of every media object, the
46
+ other service's table had been modelled for weeks, and this one had no entity, no fields, no
47
+ rotation story. A contradiction needs two sides. Absence has one. The register that finally caught
48
+ it checks *entity → table* and *table → entity*, and **only the second direction found anything**:
49
+ four entities fully specified, cited by build tasks, with no schema anywhere.
50
+
51
+ **3 · Closure against the artefact.** Two gaps were marked **closed** while the design still
52
+ violated them — the closure had been verified by reading the specification, which had been fixed,
53
+ while the frames had not. Twice is a category, so every drawn screen now carries a marker naming the
54
+ newest decision its *frames* were checked against, and the linter fails when the prose cites
55
+ something newer.
56
+
57
+ **4 and 5 · Probes.** Every check written was exercised against a planted defect. **Five probes
58
+ failed before any check did:** one added a definition where the check looks for an unresolved
59
+ reference; one edited a string whose whitespace did not match; one hit the first prose mention
60
+ instead of the table row; one flipped a row whose producer cell was empty, so nothing was planted;
61
+ one counted matching lines and counted the check's own `INFO` line as a hit. Four times out of five
62
+ the probe was wrong, not the check.
63
+
64
+ **6 · Sweep the class.** A pass fixed four invented audit-action names in a table and stopped at the
65
+ rows it was looking at; two rows in the same table still said something else, found the next day.
66
+ The same shape recurred three times — a retired word corrected on one screen and left on two others,
67
+ a value fixed in a light frame and left in its dark twin, a stale retention window removed from
68
+ three documents' prose and surviving in a design.
69
+
70
+ **8 · Compute.** Two documents had to stop quoting totals after they went stale. The register that
71
+ replaced them computes its cross-reference column from lines the tables themselves carry, so the two
72
+ cannot disagree.
73
+
74
+ **9 · Seeds green.** A documentation gate added to a scaffold **failed on its own seeds** — it read
75
+ the template block and the allocation line as real identifiers. A project that starts red teaches
76
+ everyone on day one that the gate is noise.
77
+
78
+ **10 · Measure the detector.** A parity-based check for unbalanced markup produced **six false
79
+ positives out of six** on the real corpus. It was discarded for a deterministic rule. A gate that
80
+ cries wolf is removed by the third person who hits it.
81
+
82
+ **11 · Exit codes.** A repository's docs gate appended a check *after* its verdict block, so it
83
+ printed `FAIL` and returned `0`. CI had been green over it for an unknown period.
84
+
85
+ **12 · Cold runs.** An isolation test read whatever another test file had left in the database. Test
86
+ files run alphabetically and the one that creates that data runs later, so the test **passed on a
87
+ warm database and failed on a cold one** — which is what every new developer has.
88
+
89
+ **13 · Ports.** A dev compose published the default Postgres and Redis ports. The machine already
90
+ ran both, so the containers were silently shadowed: the tools connected to the host's services and
91
+ the migration failed with a permission error that named nothing about the collision.
92
+
93
+ **14 · Absent targets.** A repository's first instruction to every agent was to run a command that
94
+ was not installed, with no install line anywhere and no statement of what a session without it
95
+ actually is.
96
+
97
+ ---
98
+
99
+ ## The two that are not in the table, and why
100
+
101
+ Kept as review questions, because no check can decide them:
102
+
103
+ - **Is this the right citation?** A stale reference was replaced with a *false* one — the new target
104
+ existed and said nothing about the subject. A gate can prove an identifier resolves; only a reader
105
+ can prove it is the right one. **Ask at review: did you open the target and confirm it says the
106
+ thing?**
107
+ - **Does the prose match the contract, or another paragraph of prose?** A "correction" to an attempt
108
+ cap introduced a second vocabulary for one counter, because it was written against a description
109
+ instead of the schema. **Ask at review: which artefact did this number come from?**
110
+
111
+ ---
112
+
113
+ ## The one instruction that would have prevented the most
114
+
115
+ > **Before trusting any tool's report about the world, make it report something you can already
116
+ > verify.**
117
+
118
+ Four of the worst failures on that project were the same failure wearing different clothes: a test
119
+ suite reporting green having skipped every assertion; a gate printing `FAIL` and exiting `0`;
120
+ containers reporting healthy while the tools talked to the host's services; a coordination plugin
121
+ reporting a lease held by an identity that belonged to a different session. In each case the tool
122
+ was describing a world it was not looking at, and in each case one deliberate check against a known
123
+ answer would have exposed it in a minute.
124
+
125
+ ---
126
+
127
+ ## Where these bind in the pipeline
128
+
129
+ | Stage | Rules that apply |
130
+ |---|---|
131
+ | 3 Spec · 4 Plan | 2 (both directions), 8 (compute, never restate) |
132
+ | 5 Dev | 9 (generators seed green), 12 (tests create their own state), 13 (local infra) |
133
+ | 6 Tests | 4, 5, 10, 11 — every new check probed both ways, measured, and asserted on its exit code |
134
+ | 9 Docs | 8, 14 — every number computed, every target resolvable |
135
+ | 10 Acceptance | 1, 3, 6, 7 — axis rotation recorded, closure verified against artefacts, classes swept, ratchets printed |
@@ -309,7 +309,7 @@ stages/agents/types (see SKILL.md → *Bring your own skills*).
309
309
  reports nothing **for the parent as well as every submodule**:
310
310
  `git submodule status` (no line starting `+`), plus `git -C <repo> status
311
311
  --porcelain` and `git -C <repo> log @{u}..HEAD --oneline` per repo. With
312
- [agent-sync](https://github.com/appvillis-com/agent-sync) installed,
312
+ [agent-sync](https://github.com/ssheleg/agent-sync) installed,
313
313
  `/agent-sync finish` runs exactly that. The fix is two commands and the second is
314
314
  the forgotten one: `git -C <submodule> push`, then
315
315
  `git add <submodule> && git commit`.