Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message
implement-kanban
petar-spasic/laravel-house
claude-code
kanban-install
board-upgrades
worktrees
team-sync
docker-compose
deploy-keys

Adoption checklist that puts a Laravel project on the kanban board shipped with petar-spasic/laravel-house: prerequisites, `kanban:install`, the project's decisions archived and its open questions put on cards, a Claude Code restart with the lease takeover, the card-ready stack checked by `kanban doctor`, a first real card through the agent loop and the first publish. Also upgrades a board: consolidating several boards and a decisions board into one work board with epics on its cards (`fold-boards`), and judging which archived decisions become CLAUDE.md rules. Cases: an existing project whose decisions live in docs/decisions.md, a new project fresh from laravel-project-setup, a board on an older house version, and the separate kanban package. Use when the owner types /implement-kanban, to adopt the board or to upgrade it. Triggers — implement kanban, adopt the kanban board, upgrade the kanban board, fold-boards, an older board format, kanban:install, import-house-docs.

Install
php artisan boost:add-skill petar-spasic/laravel-house

Save this content to: .claude/skills/implement-kanban/SKILL.md

# Implement the kanban board

This checklist puts a project on the kanban board that ships with petar-spasic/laravel-house, or upgrades it. The rest
is owned elsewhere: the house README ("Adopting the Board" for what `kanban:install` changes, "Worktree Stacks",
"Team Sync") and the `kanban` skill (cutting cards, run loop, exit codes, questions, recovery). A defect in the
package met on the way goes upstream (the `kanban` skill, "Package findings").

## Before you start

- Run it from the main session in the main checkout, never in a worktree.
- Ask the owner before anything that touches main's data, needs sudo, pushes, or commits. Commits carry no trailers.
- The install and an upgrade can push the board with no push command. Steps 1 and 2 and "Upgrading a board" say when.

## Choose the path

| Case | You recognise it by | Steps |
|---|---|---|
| (a) An existing project | `docs/decisions.md` (and `docs/ideas.md`) hold its decisions | 1–9 |
| (b) A new project | laravel-project-setup just ran; its choices live only in this chat and the files it wrote | 1–9 |
| (c) A board on an older house version | `docs/kanban` exists, no separate kanban package; the house is behind, or `an older board format` | "Upgrading a board", (c) |
| (d) A board on the separate kanban package | `composer.json` requires the board as a package of its own | "Upgrading a board", (d) |
| (e) The separate package, no board | `composer.json` requires it, but there is no `kanban` branch, local or on `origin` | (e), then (a) or (b) |

A project still on the separate package has an older copy of this skill. The swap in the house README, "Updating the
Composer Package", brings this one; (d) step 2 and (e) are then done.

## 1. Prerequisites

The project carries `petar-spasic/laravel-house` in `require-dev`, never `petar-spasic/laravel-kanban` (case (e)). A
project without the house comes onto it with laravel-project-setup first. Then run:

```bash
php artisan kanban:install --check
```

It checks git, `main`, `origin` (reachable, not empty, a URL the container resolves), Docker Compose, the deploy key
tools and the board page. A `fail` stops the install: fix it, with the owner's OK where it pushes. Report each `warn`.
Then the owner answers what only they know:
- `origin` decides sync (house README, "Team Sync"). The install publishes the board branch (`kanban`, never `main`)
  and pushes every later write. The owner confirms the repository is private, and that the board is shared or stays on
  this machine (then `KANBAN_SYNC=off` in `.env` before step 2).
- `/kanban` has no login (laravel-deployment, Trap "Anyone who can reach the web port reads and edits the board at
  `/kanban`"). The owner chooses `KANBAN_UI_TOKEN`, `WEB_BIND=127.0.0.1`, or leaving it open.
- Without a `docker-compose.local.yml`, cards get a clone of main and no stack, and nothing merges: the merge queue
  checks each merge in a stack of its own. Ask whether that is intended.

## 2. Install

```bash
php artisan kanban:install --key=XYZ --dry-run    # read every line
php artisan kanban:install --key=XYZ
```

- `--key` is the card prefix: 2–10 uppercase letters or digits, starting with a letter. The owner picks it.
- `--dry-run` does not show the publish to `origin` (step 1 says when `KANBAN_SYNC=off` must come first).
- Read the output to the end. The `sync:` lines come just before the last line, `next: restart Claude Code`.
- A failed publish prints `sync: … (the board stays on this machine until …)` there and still exits 0. Report it.
- Every clone of a shared board runs the same house version: commit `composer.lock`.
- **Deploy key** (ssh `origin` and the local compose file): the install prints it once, when it makes it. It lives in
  `.git/laravel-house/deploy_key`, never committed; `cat .git/laravel-house/deploy_key.pub` shows it again. Show the
  owner the public half and the settings link (github.com origins only). A repository admin adds it with write access;
  run `gh repo deploy-key add …` only when the owner says so. It is a repository-wide write key the app container can
  read. With no compose file at install, no key is made: step 6 makes it once the file exists.

## 3. Record the decisions, before the restart

**Path (a):**
1. Run `vendor/bin/kanban import-house-docs --dry-run` and fix each warning in the files. Then run
   `vendor/bin/kanban import-house-docs --remove-sources`: decided and dropped entries go into
   `docs/kanban/decisions.md`, floated ideas become backlog spikes carrying their question, and the two files are
   deleted once the board holds every entry. Fix each line it prints as `still points at it:`.
2. Judge the archive (below, "Judging decisions").

**Path (b):** setup and deployment wrote their choices into the `CLAUDE.md` files already. Every open item becomes a
card with its question, as the `kanban` skill's "Questions and rules" says.

**Both:** in the root `CLAUDE.md`, the decided/open prose becomes a pointer: rules are in the `CLAUDE.md` files, open
questions ride on their cards (`vendor/bin/kanban list --all` shows the blocked ones). Without `config/house.php`,
"Where the docs live" gets this row (with it, that table is a house guideline and the Kanban block names the board):

```markdown
| `docs/kanban/` (branch `kanban`) | The board: one work board, cards grouped by `area:*`, open questions on their cards; `decisions.md` archives older decisions. Use only `vendor/bin/kanban` |
```

Bugs the owner names become cards on `work`, each on an area.

## 4. Restart Claude Code

Run `/exit`, then `claude --continue`. Agents and hooks load only at session start. Restart again after any
`doctor --fix`.
If `vendor/bin/kanban status` shows the pre-restart session holding the lease, run `vendor/bin/kanban lease --takeover`.

## 5. The stack

- **Path (b):** laravel-deployment built it worktree-ready. Step 6 only checks it.
- **Path (a):** bring compose, entrypoints, Caddy, Vite and phpunit to laravel-deployment's shapes ("Many stacks from
  one local compose": its Procedure renders them), and the seeders to laravel-project-setup's seeding standard.
  `doctor --fix` adds the card-stack lines to a local compose file written before them, and the app's
  `dockerfile: ${KANBAN_DOCKERFILE:-Dockerfile.local}` once `Dockerfile.agent` is there. Dropping `container_name` and
  volume `name:`s renames main's volumes, so the data moves once (about 2 minutes of downtime):

```bash
  docker compose -f docker-compose.local.yml down          # the old file: containers go, volumes stay
  # land the new files; main .env += COMPOSE_PROJECT_NAME={{app}}-local
  docker compose -f docker-compose.local.yml up --no-start --build
  docker run --rm --entrypoint sh -v <old postgres volume>:/from:ro -v {{app}}-local_postgres_local:/to postgres:16-alpine -c 'cp -a /from/. /to/'
  docker compose -f docker-compose.local.yml up -d --wait
  ```

  Redis may start empty (cache, queue and sessions only). The old volumes and image go a week later, with the owner.

## 6. Doctor

Run `vendor/bin/kanban doctor` and `vendor/bin/kanban validate` on the host, never in the container (doctor sees host
paths). No `fail` may remain. These clear only with the owner:
- `finish.check names no suite`: the merge queue merges nothing until it does. With the owner, set `finish.check` in
  `config/kanban.php` (publish it first: `php artisan vendor:publish --tag=kanban-config`) to the whole suite as
  `tests/CLAUDE.md` names it, each command as it runs inside the app container (on the host with
  `KANBAN_AGENT_SHELL=host`). A suite that runs longer than 30 min gets an entry with its own timeout (house README,
  "The Merge Queue"). A `warn` that it names docker, compose or `kanban-exec`: the same command without them.
- `worktree stacks disabled`: nothing merges until the project has a local compose file (laravel-deployment).

Read every `warn`:
- `no deploy key …`: `vendor/bin/kanban doctor --fix` makes it and prints the public key on a line of its own.
  The owner registers it (step 2), then restart (step 4). `ok deploy key` only means the file exists, not that the
  repository knows it.
- `sync off but this board is published`: the owner turns sync on (delete `KANBAN_SYNC=off` from `.env`, or the
  pinned `sync` line in `config/kanban.php`), or keeps sync off and accepts that the board lives on this machine only.
- `last sync failed`: stop and report.
- A Docker address-pool `warn` is the owner's sudo step.

**The main stack** passes laravel-deployment's "Verify": `/kanban` answers 200 from the URL the browser uses. With sync
on, and an ssh `origin` with the deploy key registered (step 2, or the key `doctor --fix` printed) or an https
`origin` with `KANBAN_GIT_TOKEN` set, run
`docker compose -f docker-compose.local.yml exec app vendor/bin/kanban sync` as the compose user, never `-u root`. It
prints `sync: up to date`, `pulled` or `pushed`. Anything else: laravel-deployment, Trap "The board in `/kanban` shows
*Not synced* or *Not pushed*, or never shows others' changes". The page is no substitute: a hidden tab never syncs.

## 7. Commit main

Ask first: one commit or a few by concern. Board writes are already commits on `kanban`; main's `git status` ends clean.
Then `vendor/bin/kanban publish`: the merge queue merges onto `origin`'s main, and a commit left only here makes the
main checkout diverge from it.

## 8. First card through the loop

Path (b) takes the first real feature; path (a) a real bug or feature, cut as the `kanban` skill's "Cutting cards"
says, and `promote` it: a planner plans it, then a worker builds it. Run the board as the `kanban` skill's "Running the
board" says, until the card is done.
- With sync on, `start` is won by the push that lands, so `origin` must be reachable and writable from the host.
- Exit 9: stop and report. Never loop; never add `KANBAN_SYNC=off` yourself. The `kanban` skill owns the exit table.

## 9. Publish and report

`vendor/bin/kanban publish` syncs the board, then pushes `main` only when it holds commits made outside the merge
queue; it never merges. Each merge already pushed `main`.
- It pushes the board even under `KANBAN_SYNC=off`.

Report to the owner:
- the archive and the rules it added, the cards with open questions, the doctor output, `vendor/bin/kanban status`
  (sync state) and the first card's merge sha;
- the owner steps still open: address pools, old volumes, the deploy key to register;
- how the board runs from now on: "Run the board", `/kanban-status` any time, and a daily "Do the morning";
- on every other clone, before its first Claude Code session: `composer install && vendor/bin/kanban attach`. Read
  what it prints. Each clone has its own key. If a session ran first, `cat .git/laravel-house/deploy_key.pub`.

## Upgrading a board

Both cases first:

1. **Decide sync.** With an `origin` and no `KANBAN_SYNC` anywhere, the first `status` or session start after the
   upgrade pushes the board. Only `sync auto (on)` in the status line shows it. To keep the board local, set
   `KANBAN_SYNC=off` in `.env` first. A `config/kanban.php` published earlier pins
   `'sync' => env('KANBAN_SYNC', 'off')`; sync then stays off until that line is deleted or set to `'auto'`. The
   `sync off but this board is published` warning appears only once the board is on `origin`.
2. **The board page** has no login. Ask whether the stack is visible beyond this machine (step 1, "The board page").

**(c) On an older house version:** update the house as the README's "Updating" says, its warnings for each version
crossed first (a `^0.x` caret never crosses a minor), then "Consolidating" when `status` says `an older board format`,
step 6, the commit and `publish` (step 7) and a restart (step 4).

**(d) On the separate package.** Every clone does this. Upgrade every project on a machine before starting new
worktree stacks there: the port registry is machine-wide.

1. **No live agents:** `vendor/bin/kanban status` shows none, or the migration refuses the rename partway.
2. Run it in one shell call. Between the remove and `doctor --fix`, the hooks name files that are gone. The house is
   required with no version, because a `^0.x` caret never crosses a minor:

```bash
   composer remove --dev petar-spasic/laravel-kanban && composer require --dev petar-spasic/laravel-house -W && vendor/bin/kanban doctor --fix && php artisan boost:update
   ```

A clone that already pulled the commit from step 5 runs, in one call,
   `composer install && vendor/bin/kanban doctor --fix && php artisan boost:update`.
3. **Read every migration line.** `doctor --fix` renames `.git/laravel-kanban` to `.git/laravel-house`, moves the
   port registry, rewrites the old markers (`CLAUDE.md`, the agents, worktree `.env` files), switches
   `core.hooksPath`, drops the old package from `boost.json` and points the local compose file at `.git/laravel-house`.
   It refuses the rename while agents are live, and then also skips `attach`, so no second deploy key is made: stop
   them and run `doctor --fix` again. A `deploy_key` it keeps in `.git/laravel-kanban` differs from the one in
   `.git/laravel-house`: keep the one the repository knows, delete the other, and run it again. A
   `stacks.json … still used by <repo>` warning stays until those projects are upgraded; the last one's `doctor --fix`
   moves the registry.
4. **The container's half:** openssh-client in `Dockerfile.local`, `GIT_SSH_COMMAND` (both paths under
   `.git/laravel-house`, as `${KANBAN_GIT_SSH_COMMAND-…}`) and the `user:` line in the local compose, merged per
   laravel-deployment's Procedure, step 2 (`doctor --fix` adds the card-stack lines).
   Then rebuild and recreate with `docker compose -f docker-compose.local.yml up -d --build --wait`. Without
   `--build` the container has no ssh.
5. **Consolidate:** "Consolidating" below (the board is in the older format until then, so `doctor` fails).
6. **Finish:** step 6's container check, the commit and `publish` (step 7), restart (step 4).

**(e) The separate package, no board.** Swap the packages, with no `doctor`, then adopt the board by path (a) or (b):

```bash
composer remove --dev petar-spasic/laravel-kanban && composer require --dev petar-spasic/laravel-house -W && php artisan boost:update
```

## Consolidating

A board from before version 3 (`an older board format: the owner runs /implement-kanban`) keeps its boards inside
epic directories, and maybe a decisions board. Every command but `sync`, `doctor`, `attach` and `kanban:install` refuses
until it is consolidated.

1. **Drain:** no card in doing or review, on the house version the board runs now (`finish` or `stop` them with the
   owner).
2. **Every clone runs the new house** before anyone writes: the merge driver must write the same bytes everywhere.
3. `vendor/bin/kanban fold-boards --dry-run`, and show the owner every line: the moves, the archived decisions, each
   epic and its card count, each open question and the cards it lands on, the cards with no area, and the startable
   areas against `max_parallel`. Each old epic directory becomes an epic on its cards; the installer's `project` gives
   none.
4. `vendor/bin/kanban fold-boards`. It runs the stored-name migration first, then makes one commit and pushes it. With
   sync off, `vendor/bin/kanban sync` once it is on.
5. Cards that got the same question are usually one piece of work: `kanban fold A B --into=C`.
6. Give every open card an `area:*` label (`set ID labels=+area:…`), with areas sized as the `kanban` skill's "Cutting
   cards" says; then re-cut with the owner: fold enabler cards, group small ones. An epic that is really a permanent
   part of the product (UI, Backend) becomes an area instead: `set ID labels=+area:… epic=` on its cards.
7. "Judging decisions", then `vendor/bin/kanban validate` and `doctor`.

## Judging decisions

`docs/kanban/decisions.md` holds every decision as it was decided; nothing reads it unless asked. Go through it once,
entry by entry, and only then:

- **Skip** an entry that is already enforced (a template, a gate, the code itself), already a rule in a `CLAUDE.md`,
  superseded, or a one-off choice that shaped one piece of work.
- **Otherwise** write one imperative line in the `CLAUDE.md` of the directory it governs, without the history.
- Aim for at most one line per three entries; every line is read by every agent on every card.
- Show the owner the diff and the skipped entries with a reason each; commit on main with the owner's OK, then
  `vendor/bin/kanban publish`.

Implement the kanban board

This checklist puts a project on the kanban board that ships with petar-spasic/laravel-house, or upgrades it. The rest is owned elsewhere: the house README ("Adopting the Board" for what kanban:install changes, "Worktree Stacks", "Team Sync") and the kanban skill (cutting cards, run loop, exit codes, questions, recovery). A defect in the package met on the way goes upstream (the kanban skill, "Package findings").

Before you start

  • Run it from the main session in the main checkout, never in a worktree.
  • Ask the owner before anything that touches main's data, needs sudo, pushes, or commits. Commits carry no trailers.
  • The install and an upgrade can push the board with no push command. Steps 1 and 2 and "Upgrading a board" say when.

Choose the path

Case You recognise it by Steps
(a) An existing project docs/decisions.md (and docs/ideas.md) hold its decisions 1–9
(b) A new project laravel-project-setup just ran; its choices live only in this chat and the files it wrote 1–9
(c) A board on an older house version docs/kanban exists, no separate kanban package; the house is behind, or an older board format "Upgrading a board", (c)
(d) A board on the separate kanban package composer.json requires the board as a package of its own "Upgrading a board", (d)
(e) The separate package, no board composer.json requires it, but there is no kanban branch, local or on origin (e), then (a) or (b)

A project still on the separate package has an older copy of this skill. The swap in the house README, "Updating the Composer Package", brings this one; (d) step 2 and (e) are then done.

1. Prerequisites

The project carries petar-spasic/laravel-house in require-dev, never petar-spasic/laravel-kanban (case (e)). A project without the house comes onto it with laravel-project-setup first. Then run:

php artisan kanban:install --check

It checks git, main, origin (reachable, not empty, a URL the container resolves), Docker Compose, the deploy key tools and the board page. A fail stops the install: fix it, with the owner's OK where it pushes. Report each warn. Then the owner answers what only they know:

  • origin decides sync (house README, "Team Sync"). The install publishes the board branch (kanban, never main) and pushes every later write. The owner confirms the repository is private, and that the board is shared or stays on this machine (then KANBAN_SYNC=off in .env before step 2).
  • /kanban has no login (laravel-deployment, Trap "Anyone who can reach the web port reads and edits the board at /kanban"). The owner chooses KANBAN_UI_TOKEN, WEB_BIND=127.0.0.1, or leaving it open.
  • Without a docker-compose.local.yml, cards get a clone of main and no stack, and nothing merges: the merge queue checks each merge in a stack of its own. Ask whether that is intended.

2. Install

php artisan kanban:install --key=XYZ --dry-run    # read every line
php artisan kanban:install --key=XYZ
  • --key is the card prefix: 2–10 uppercase letters or digits, starting with a letter. The owner picks it.
  • --dry-run does not show the publish to origin (step 1 says when KANBAN_SYNC=off must come first).
  • Read the output to the end. The sync: lines come just before the last line, next: restart Claude Code.
  • A failed publish prints sync: … (the board stays on this machine until …) there and still exits 0. Report it.
  • Every clone of a shared board runs the same house version: commit composer.lock.
  • Deploy key (ssh origin and the local compose file): the install prints it once, when it makes it. It lives in .git/laravel-house/deploy_key, never committed; cat .git/laravel-house/deploy_key.pub shows it again. Show the owner the public half and the settings link (github.com origins only). A repository admin adds it with write access; run gh repo deploy-key add … only when the owner says so. It is a repository-wide write key the app container can read. With no compose file at install, no key is made: step 6 makes it once the file exists.

3. Record the decisions, before the restart

Path (a):

  1. Run vendor/bin/kanban import-house-docs --dry-run and fix each warning in the files. Then run vendor/bin/kanban import-house-docs --remove-sources: decided and dropped entries go into docs/kanban/decisions.md, floated ideas become backlog spikes carrying their question, and the two files are deleted once the board holds every entry. Fix each line it prints as still points at it:.
  2. Judge the archive (below, "Judging decisions").

Path (b): setup and deployment wrote their choices into the CLAUDE.md files already. Every open item becomes a card with its question, as the kanban skill's "Questions and rules" says.

Both: in the root CLAUDE.md, the decided/open prose becomes a pointer: rules are in the CLAUDE.md files, open questions ride on their cards (vendor/bin/kanban list --all shows the blocked ones). Without config/house.php, "Where the docs live" gets this row (with it, that table is a house guideline and the Kanban block names the board):

| `docs/kanban/` (branch `kanban`) | The board: one work board, cards grouped by `area:*`, open questions on their cards; `decisions.md` archives older decisions. Use only `vendor/bin/kanban` |

Bugs the owner names become cards on work, each on an area.

4. Restart Claude Code

Run /exit, then claude --continue. Agents and hooks load only at session start. Restart again after any doctor --fix. If vendor/bin/kanban status shows the pre-restart session holding the lease, run vendor/bin/kanban lease --takeover.

5. The stack

  • Path (b): laravel-deployment built it worktree-ready. Step 6 only checks it.
  • Path (a): bring compose, entrypoints, Caddy, Vite and phpunit to laravel-deployment's shapes ("Many stacks from one local compose": its Procedure renders them), and the seeders to laravel-project-setup's seeding standard. doctor --fix adds the card-stack lines to a local compose file written before them, and the app's dockerfile: ${KANBAN_DOCKERFILE:-Dockerfile.local} once Dockerfile.agent is there. Dropping container_name and volume name:s renames main's volumes, so the data moves once (about 2 minutes of downtime):
  docker compose -f docker-compose.local.yml down          # the old file: containers go, volumes stay
  # land the new files; main .env += COMPOSE_PROJECT_NAME={{app}}-local
  docker compose -f docker-compose.local.yml up --no-start --build
  docker run --rm --entrypoint sh -v <old postgres volume>:/from:ro -v {{app}}-local_postgres_local:/to postgres:16-alpine -c 'cp -a /from/. /to/'
  docker compose -f docker-compose.local.yml up -d --wait

Redis may start empty (cache, queue and sessions only). The old volumes and image go a week later, with the owner.

6. Doctor

Run vendor/bin/kanban doctor and vendor/bin/kanban validate on the host, never in the container (doctor sees host paths). No fail may remain. These clear only with the owner:

  • finish.check names no suite: the merge queue merges nothing until it does. With the owner, set finish.check in config/kanban.php (publish it first: php artisan vendor:publish --tag=kanban-config) to the whole suite as tests/CLAUDE.md names it, each command as it runs inside the app container (on the host with KANBAN_AGENT_SHELL=host). A suite that runs longer than 30 min gets an entry with its own timeout (house README, "The Merge Queue"). A warn that it names docker, compose or kanban-exec: the same command without them.
  • worktree stacks disabled: nothing merges until the project has a local compose file (laravel-deployment).

Read every warn:

  • no deploy key …: vendor/bin/kanban doctor --fix makes it and prints the public key on a line of its own. The owner registers it (step 2), then restart (step 4). ok deploy key only means the file exists, not that the repository knows it.
  • sync off but this board is published: the owner turns sync on (delete KANBAN_SYNC=off from .env, or the pinned sync line in config/kanban.php), or keeps sync off and accepts that the board lives on this machine only.
  • last sync failed: stop and report.
  • A Docker address-pool warn is the owner's sudo step.

The main stack passes laravel-deployment's "Verify": /kanban answers 200 from the URL the browser uses. With sync on, and an ssh origin with the deploy key registered (step 2, or the key doctor --fix printed) or an https origin with KANBAN_GIT_TOKEN set, run docker compose -f docker-compose.local.yml exec app vendor/bin/kanban sync as the compose user, never -u root. It prints sync: up to date, pulled or pushed. Anything else: laravel-deployment, Trap "The board in /kanban shows Not synced or Not pushed, or never shows others' changes". The page is no substitute: a hidden tab never syncs.

7. Commit main

Ask first: one commit or a few by concern. Board writes are already commits on kanban; main's git status ends clean. Then vendor/bin/kanban publish: the merge queue merges onto origin's main, and a commit left only here makes the main checkout diverge from it.

8. First card through the loop

Path (b) takes the first real feature; path (a) a real bug or feature, cut as the kanban skill's "Cutting cards" says, and promote it: a planner plans it, then a worker builds it. Run the board as the kanban skill's "Running the board" says, until the card is done.

  • With sync on, start is won by the push that lands, so origin must be reachable and writable from the host.
  • Exit 9: stop and report. Never loop; never add KANBAN_SYNC=off yourself. The kanban skill owns the exit table.

9. Publish and report

vendor/bin/kanban publish syncs the board, then pushes main only when it holds commits made outside the merge queue; it never merges. Each merge already pushed main.

  • It pushes the board even under KANBAN_SYNC=off.

Report to the owner:

  • the archive and the rules it added, the cards with open questions, the doctor output, vendor/bin/kanban status (sync state) and the first card's merge sha;
  • the owner steps still open: address pools, old volumes, the deploy key to register;
  • how the board runs from now on: "Run the board", /kanban-status any time, and a daily "Do the morning";
  • on every other clone, before its first Claude Code session: composer install && vendor/bin/kanban attach. Read what it prints. Each clone has its own key. If a session ran first, cat .git/laravel-house/deploy_key.pub.

Upgrading a board

Both cases first:

  1. Decide sync. With an origin and no KANBAN_SYNC anywhere, the first status or session start after the upgrade pushes the board. Only sync auto (on) in the status line shows it. To keep the board local, set KANBAN_SYNC=off in .env first. A config/kanban.php published earlier pins 'sync' => env('KANBAN_SYNC', 'off'); sync then stays off until that line is deleted or set to 'auto'. The sync off but this board is published warning appears only once the board is on origin.
  2. The board page has no login. Ask whether the stack is visible beyond this machine (step 1, "The board page").

(c) On an older house version: update the house as the README's "Updating" says, its warnings for each version crossed first (a ^0.x caret never crosses a minor), then "Consolidating" when status says an older board format, step 6, the commit and publish (step 7) and a restart (step 4).

(d) On the separate package. Every clone does this. Upgrade every project on a machine before starting new worktree stacks there: the port registry is machine-wide.

  1. No live agents: vendor/bin/kanban status shows none, or the migration refuses the rename partway.
  2. Run it in one shell call. Between the remove and doctor --fix, the hooks name files that are gone. The house is required with no version, because a ^0.x caret never crosses a minor:
   composer remove --dev petar-spasic/laravel-kanban && composer require --dev petar-spasic/laravel-house -W && vendor/bin/kanban doctor --fix && php artisan boost:update

A clone that already pulled the commit from step 5 runs, in one call, composer install && vendor/bin/kanban doctor --fix && php artisan boost:update. 3. Read every migration line. doctor --fix renames .git/laravel-kanban to .git/laravel-house, moves the port registry, rewrites the old markers (CLAUDE.md, the agents, worktree .env files), switches core.hooksPath, drops the old package from boost.json and points the local compose file at .git/laravel-house. It refuses the rename while agents are live, and then also skips attach, so no second deploy key is made: stop them and run doctor --fix again. A deploy_key it keeps in .git/laravel-kanban differs from the one in .git/laravel-house: keep the one the repository knows, delete the other, and run it again. A stacks.json … still used by <repo> warning stays until those projects are upgraded; the last one's doctor --fix moves the registry. 4. The container's half: openssh-client in Dockerfile.local, GIT_SSH_COMMAND (both paths under .git/laravel-house, as ${KANBAN_GIT_SSH_COMMAND-…}) and the user: line in the local compose, merged per laravel-deployment's Procedure, step 2 (doctor --fix adds the card-stack lines). Then rebuild and recreate with docker compose -f docker-compose.local.yml up -d --build --wait. Without --build the container has no ssh. 5. Consolidate: "Consolidating" below (the board is in the older format until then, so doctor fails). 6. Finish: step 6's container check, the commit and publish (step 7), restart (step 4).

(e) The separate package, no board. Swap the packages, with no doctor, then adopt the board by path (a) or (b):

composer remove --dev petar-spasic/laravel-kanban && composer require --dev petar-spasic/laravel-house -W && php artisan boost:update

Consolidating

A board from before version 3 (an older board format: the owner runs /implement-kanban) keeps its boards inside epic directories, and maybe a decisions board. Every command but sync, doctor, attach and kanban:install refuses until it is consolidated.

  1. Drain: no card in doing or review, on the house version the board runs now (finish or stop them with the owner).
  2. Every clone runs the new house before anyone writes: the merge driver must write the same bytes everywhere.
  3. vendor/bin/kanban fold-boards --dry-run, and show the owner every line: the moves, the archived decisions, each epic and its card count, each open question and the cards it lands on, the cards with no area, and the startable areas against max_parallel. Each old epic directory becomes an epic on its cards; the installer's project gives none.
  4. vendor/bin/kanban fold-boards. It runs the stored-name migration first, then makes one commit and pushes it. With sync off, vendor/bin/kanban sync once it is on.
  5. Cards that got the same question are usually one piece of work: kanban fold A B --into=C.
  6. Give every open card an area:* label (set ID labels=+area:…), with areas sized as the kanban skill's "Cutting cards" says; then re-cut with the owner: fold enabler cards, group small ones. An epic that is really a permanent part of the product (UI, Backend) becomes an area instead: set ID labels=+area:… epic= on its cards.
  7. "Judging decisions", then vendor/bin/kanban validate and doctor.

Judging decisions

docs/kanban/decisions.md holds every decision as it was decided; nothing reads it unless asked. Go through it once, entry by entry, and only then:

  • Skip an entry that is already enforced (a template, a gate, the code itself), already a rule in a CLAUDE.md, superseded, or a one-off choice that shaped one piece of work.
  • Otherwise write one imperative line in the CLAUDE.md of the directory it governs, without the history.
  • Aim for at most one line per three entries; every line is read by every agent on every card.
  • Show the owner the diff and the skipped entries with a reason each; commit on main with the owner's OK, then vendor/bin/kanban publish.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib