@codyswann/lisa 2.154.1 → 2.155.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.
Files changed (67) hide show
  1. package/package.json +1 -1
  2. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  3. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  4. package/plugins/lisa/commands/validate-tracker-mapping.md +15 -0
  5. package/plugins/lisa/skills/setup-automations/SKILL.md +9 -5
  6. package/plugins/lisa/skills/validate-tracker-mapping/SKILL.md +188 -0
  7. package/plugins/lisa/skills/validate-tracker-mapping/agents/openai.yaml +4 -0
  8. package/plugins/lisa-agy/commands/validate-tracker-mapping.md +15 -0
  9. package/plugins/lisa-agy/plugin.json +1 -1
  10. package/plugins/lisa-agy/skills/setup-automations/SKILL.md +9 -5
  11. package/plugins/lisa-agy/skills/validate-tracker-mapping/SKILL.md +188 -0
  12. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  13. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  14. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  15. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  16. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  17. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  18. package/plugins/lisa-copilot/commands/validate-tracker-mapping.md +15 -0
  19. package/plugins/lisa-copilot/skills/setup-automations/SKILL.md +9 -5
  20. package/plugins/lisa-copilot/skills/validate-tracker-mapping/SKILL.md +188 -0
  21. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  22. package/plugins/lisa-cursor/commands/validate-tracker-mapping.md +15 -0
  23. package/plugins/lisa-cursor/skills/setup-automations/SKILL.md +9 -5
  24. package/plugins/lisa-cursor/skills/validate-tracker-mapping/SKILL.md +188 -0
  25. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  26. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  27. package/plugins/lisa-expo-agy/plugin.json +1 -1
  28. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  29. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  30. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  31. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  32. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  33. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  34. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  35. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  36. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  37. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  38. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  39. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  40. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  41. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  42. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  43. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  44. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  45. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  46. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  47. package/plugins/lisa-rails-agy/plugin.json +1 -1
  48. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  49. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  50. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  51. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  52. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  53. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  54. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  55. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  56. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  57. package/plugins/lisa-wiki/skills/lisa-wiki-setup-automations/SKILL.md +8 -5
  58. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  59. package/plugins/lisa-wiki-agy/skills/lisa-wiki-setup-automations/SKILL.md +8 -5
  60. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  61. package/plugins/lisa-wiki-copilot/skills/lisa-wiki-setup-automations/SKILL.md +8 -5
  62. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  63. package/plugins/lisa-wiki-cursor/skills/lisa-wiki-setup-automations/SKILL.md +8 -5
  64. package/plugins/src/base/commands/validate-tracker-mapping.md +15 -0
  65. package/plugins/src/base/skills/setup-automations/SKILL.md +9 -5
  66. package/plugins/src/base/skills/validate-tracker-mapping/SKILL.md +188 -0
  67. package/plugins/src/wiki/skills/lisa-wiki-setup-automations/SKILL.md +8 -5
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.154.1",
3
+ "version": "2.155.1",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.154.1",
3
+ "version": "2.155.1",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.154.1",
3
+ "version": "2.155.1",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.154.1",
3
+ "version": "2.155.1",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.154.1",
3
+ "version": "2.155.1",
4
4
  "description": "TypeScript-specific hooks for formatting, linting, and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.154.1",
3
+ "version": "2.155.1",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.154.1",
3
+ "version": "2.155.1",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.154.1",
3
+ "version": "2.155.1",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.154.1",
3
+ "version": "2.155.1",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.154.1",
3
+ "version": "2.155.1",
4
4
  "description": "Distributable LLM Wiki kernel — ingest, query, lint, and maintain a git-native markdown knowledge base across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -43,11 +43,14 @@ independent and use disjoint name prefixes, so running both is safe.
43
43
  The automation runs **one cycle** of the full wiki ingest and respects that command's own confirmation
44
44
  and commit/PR policy (never ask before running; run a full ingest across every enabled
45
45
  non-external-write source; commit/PR per the ingest skill's bookends; report the cycle summary).
46
- Before running the ingest, the automation must sync its checkout: fetch the default remote branch and
47
- rebase the current automation branch onto it (for the common GitHub case, `origin/main`). If the
48
- checkout is already on the default branch, fast-forward/rebase it to the remote default. If the
49
- rebase has conflicts or the working tree is dirty in a way the automation did not create, abort the
50
- rebase and report the blocker instead of ingesting from stale code.
46
+ Before running the ingest, the automation must attempt to sync its checkout: fetch the default remote
47
+ branch and rebase the current automation branch onto it (for the common GitHub case, `origin/main`).
48
+ If the checkout is already on the default branch, fast-forward/rebase it to the remote default. A
49
+ dirty working tree is not by itself a blocker: capture `git status --short --branch`, leave
50
+ pre-existing changes untouched, and continue when sync and ingest can run without overwriting those
51
+ paths. Abort only when Git reports an actual sync conflict or ingest would need to modify an
52
+ already-dirty path; in that case leave existing queue/wiki state unchanged and report the exact
53
+ conflicting path(s).
51
54
 
52
55
  | Automation | Command it runs | Cadence |
53
56
  |---|---|---|
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.154.1",
3
+ "version": "2.155.1",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -43,11 +43,14 @@ independent and use disjoint name prefixes, so running both is safe.
43
43
  The automation runs **one cycle** of the full wiki ingest and respects that command's own confirmation
44
44
  and commit/PR policy (never ask before running; run a full ingest across every enabled
45
45
  non-external-write source; commit/PR per the ingest skill's bookends; report the cycle summary).
46
- Before running the ingest, the automation must sync its checkout: fetch the default remote branch and
47
- rebase the current automation branch onto it (for the common GitHub case, `origin/main`). If the
48
- checkout is already on the default branch, fast-forward/rebase it to the remote default. If the
49
- rebase has conflicts or the working tree is dirty in a way the automation did not create, abort the
50
- rebase and report the blocker instead of ingesting from stale code.
46
+ Before running the ingest, the automation must attempt to sync its checkout: fetch the default remote
47
+ branch and rebase the current automation branch onto it (for the common GitHub case, `origin/main`).
48
+ If the checkout is already on the default branch, fast-forward/rebase it to the remote default. A
49
+ dirty working tree is not by itself a blocker: capture `git status --short --branch`, leave
50
+ pre-existing changes untouched, and continue when sync and ingest can run without overwriting those
51
+ paths. Abort only when Git reports an actual sync conflict or ingest would need to modify an
52
+ already-dirty path; in that case leave existing queue/wiki state unchanged and report the exact
53
+ conflicting path(s).
51
54
 
52
55
  | Automation | Command it runs | Cadence |
53
56
  |---|---|---|
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.154.1",
3
+ "version": "2.155.1",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -43,11 +43,14 @@ independent and use disjoint name prefixes, so running both is safe.
43
43
  The automation runs **one cycle** of the full wiki ingest and respects that command's own confirmation
44
44
  and commit/PR policy (never ask before running; run a full ingest across every enabled
45
45
  non-external-write source; commit/PR per the ingest skill's bookends; report the cycle summary).
46
- Before running the ingest, the automation must sync its checkout: fetch the default remote branch and
47
- rebase the current automation branch onto it (for the common GitHub case, `origin/main`). If the
48
- checkout is already on the default branch, fast-forward/rebase it to the remote default. If the
49
- rebase has conflicts or the working tree is dirty in a way the automation did not create, abort the
50
- rebase and report the blocker instead of ingesting from stale code.
46
+ Before running the ingest, the automation must attempt to sync its checkout: fetch the default remote
47
+ branch and rebase the current automation branch onto it (for the common GitHub case, `origin/main`).
48
+ If the checkout is already on the default branch, fast-forward/rebase it to the remote default. A
49
+ dirty working tree is not by itself a blocker: capture `git status --short --branch`, leave
50
+ pre-existing changes untouched, and continue when sync and ingest can run without overwriting those
51
+ paths. Abort only when Git reports an actual sync conflict or ingest would need to modify an
52
+ already-dirty path; in that case leave existing queue/wiki state unchanged and report the exact
53
+ conflicting path(s).
51
54
 
52
55
  | Automation | Command it runs | Cadence |
53
56
  |---|---|---|
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.154.1",
3
+ "version": "2.155.1",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -43,11 +43,14 @@ independent and use disjoint name prefixes, so running both is safe.
43
43
  The automation runs **one cycle** of the full wiki ingest and respects that command's own confirmation
44
44
  and commit/PR policy (never ask before running; run a full ingest across every enabled
45
45
  non-external-write source; commit/PR per the ingest skill's bookends; report the cycle summary).
46
- Before running the ingest, the automation must sync its checkout: fetch the default remote branch and
47
- rebase the current automation branch onto it (for the common GitHub case, `origin/main`). If the
48
- checkout is already on the default branch, fast-forward/rebase it to the remote default. If the
49
- rebase has conflicts or the working tree is dirty in a way the automation did not create, abort the
50
- rebase and report the blocker instead of ingesting from stale code.
46
+ Before running the ingest, the automation must attempt to sync its checkout: fetch the default remote
47
+ branch and rebase the current automation branch onto it (for the common GitHub case, `origin/main`).
48
+ If the checkout is already on the default branch, fast-forward/rebase it to the remote default. A
49
+ dirty working tree is not by itself a blocker: capture `git status --short --branch`, leave
50
+ pre-existing changes untouched, and continue when sync and ingest can run without overwriting those
51
+ paths. Abort only when Git reports an actual sync conflict or ingest would need to modify an
52
+ already-dirty path; in that case leave existing queue/wiki state unchanged and report the exact
53
+ conflicting path(s).
51
54
 
52
55
  | Automation | Command it runs | Cadence |
53
56
  |---|---|---|
@@ -0,0 +1,15 @@
1
+ ---
2
+ description: "Detect (and optionally repair) drift between a project's configured Lisa status/label mappings and the live tracker/source workflow names. Read-only by default; repairs the config to canonical live names with repair=true. Audits the current repo or sweeps many via projects=/workspaces=."
3
+ argument-hint: "[projects=<glob> | workspaces=<file> [filter=<substr>]] [lane=build|prd|both] [repair=true]"
4
+ ---
5
+
6
+ Use the /lisa:validate-tracker-mapping skill to check whether the status/label names in `.lisa.config.json` still match the live tracker and PRD source — catching renames, deletions, and case drift (e.g. config `On Stg` vs live `ON STG`). Read-only by default; pass `repair=true` to rewrite the config to the canonical live names. $ARGUMENTS
7
+
8
+ Common usage:
9
+
10
+ - `/lisa:validate-tracker-mapping` — audit the current repo's mapping (read-only).
11
+ - `/lisa:validate-tracker-mapping repair=true` — audit and repair config drift in the current repo.
12
+ - `/lisa:validate-tracker-mapping projects=~/workspace/geminisportsai/projects/*` — sweep every Lisa project under a directory.
13
+ - `/lisa:validate-tracker-mapping workspaces=~/workspace/lisa/.lisa.workspaces.json filter=geminisportsai` — sweep the projects in a workspaces file whose paths match a substring.
14
+
15
+ Use this when you suspect a JIRA/GitHub/Linear/Notion status, label, or option was renamed or deleted out from under Lisa — the failure mode that leaves builds unable to find their completion transition and items silently stuck. Run it read-only (or on a schedule) to detect drift; run it with `repair=true` to fix the config. Repair only ever edits the config to match the live names — it never renames anything in the tracker.
@@ -45,11 +45,15 @@ affect **only** the two exploratory automations.
45
45
 
46
46
  Each automation runs **one cycle** of a Lisa command and respects that command's confirmation policy
47
47
  (never ask before running; exit cleanly when the queue is idle; report the cycle summary).
48
- Before running the Lisa command, each automation must sync its checkout: fetch the default remote
49
- branch and rebase the current automation branch onto it (for the common GitHub case, `origin/main`).
50
- If the checkout is already on the default branch, fast-forward/rebase it to the remote default. If
51
- the rebase has conflicts or the working tree is dirty in a way the automation did not create, abort
52
- the rebase, leave queue state unchanged, and report the blocker instead of running on stale code.
48
+ Before running the Lisa command, each automation must attempt to sync its checkout.
49
+ Fetch the default remote branch, then rebase onto `origin/main` or the resolved default branch. If
50
+ the checkout is already on the default branch, fast-forward/rebase it to the remote default. A dirty
51
+ working tree is not by itself a blocker: capture
52
+ `git status --short --branch`,
53
+ leave pre-existing changes untouched, and continue when the sync and selected Lisa command can run
54
+ without overwriting those paths. Abort only when Git reports an actual sync conflict or the selected
55
+ command would need to modify an already-dirty path; in that case leave queue state unchanged and
56
+ report the exact conflicting path(s).
53
57
 
54
58
  | Automation | Command it runs | Cadence |
55
59
  |---|---|---|
@@ -0,0 +1,188 @@
1
+ ---
2
+ name: validate-tracker-mapping
3
+ description: "Detect and repair drift between a project's configured Lisa status/label mappings and the live tracker/source workflow. Compares every lifecycle role in `.lisa.config.json` (JIRA `jira.workflow` statuses, GitHub/Linear `labels.{build,prd}`, Notion `notion.values` select options, Confluence `confluence.parents`) against the authoritative live names the access layer reports — catching renames, deletions, and case drift (e.g. config `On Stg` vs live `ON STG`). Read-only by default; `repair=true` rewrites the config to the canonical live names (config is fixed, never the tracker). Audits the current repo by default, or sweeps a set of projects via `projects=<glob>` / `workspaces=<file>`. Safe to schedule for continuous drift detection."
4
+ allowed-tools: ["Skill", "Bash", "Read", "Write", "Edit", "AskUserQuestion"]
5
+ ---
6
+
7
+ # Validate Tracker Mapping: $ARGUMENTS
8
+
9
+ `/lisa:validate-tracker-mapping` answers one question: **do the status/label names this project's `.lisa.config.json` maps each lifecycle role to still exist — with the exact name — in the live tracker and PRD source?**
10
+
11
+ Lisa's lifecycle is driven by configured role → name mappings (`ready` → `"Ready"`, `done.staging` → `"On Stg"`, a GitHub `ready` build label → `"status:ready"`, a Notion `ticketed` value → `"Ticketed"`, …). When someone renames or deletes a status in JIRA, a label in GitHub/Linear, or a select option in Notion, the config silently points at a name that no longer resolves. The symptom is downstream: a build finishes but the completion transition can't be found, so the item stalls — exactly the kind of half-broken state `/lisa:repair-intake` then has to clean up. This skill catches that drift at the source: the config-to-live mapping itself.
12
+
13
+ It is the audit/repair counterpart to `/lisa:setup-jira` (and the other `setup-*` skills): where `setup-*` *establishes* the mapping interactively, this skill *re-validates an existing mapping* against the live workflow and, on request, repairs the config to match.
14
+
15
+ ## Confirmation policy
16
+
17
+ - **Default mode is read-only.** Detect drift and report. Never mutate config or the tracker.
18
+ - **`repair=true` enables writes — to the config only, never to the tracker.** Within repair mode:
19
+ - **Case drift** (the live workflow has the same name with different casing — the configured name resolves case-insensitively but the canonical case differs) is repaired automatically: rewrite the config value to the live canonical name. This is non-destructive and unambiguous.
20
+ - **Missing name** (no case-insensitive match exists in the live set — renamed beyond recognition or deleted) is **never** auto-repaired. Compute the closest live candidates and confirm via `AskUserQuestion` before writing. Default to leaving the value unchanged.
21
+ - This skill never renames or deletes anything in the tracker/source. Repair fixes the Lisa config to match reality; correcting the tracker itself is a human/admin decision made elsewhere.
22
+
23
+ ## Arguments
24
+
25
+ - (none) — audit the **current repo** (`./.lisa.config.json`).
26
+ - `projects=<glob-or-path>` — batch sweep. Expands to every directory under the glob that contains a `.lisa.config.json`. Example: `projects=~/workspace/geminisportsai/projects/*`.
27
+ - `workspaces=<file>` — batch sweep driven by a Lisa workspaces file (the `{ "<project-path>": "<branch>" }` map used by `/lisa:update-projects`). Each key is a project path to audit. Combine with `filter=<substring>` to restrict to matching paths (e.g. `filter=geminisportsai`).
28
+ - `repair=true` — enable config repair (see confirmation policy). Default `false`.
29
+ - `lane=build|prd|both` — which mapping family to check. Default `both`. `build` = the destination `tracker` workflow; `prd` = the PRD `source` status/label mapping.
30
+
31
+ Batch mode runs the identical per-project audit on each resolved project and prints one section per project plus a roll-up summary.
32
+
33
+ ## Step 1 — Resolve scope
34
+
35
+ ```bash
36
+ # Single-repo (default): the audit target is the current directory.
37
+ # Batch: expand projects=<glob> to dirs containing .lisa.config.json,
38
+ # or read workspaces=<file> keys (optionally filtered).
39
+ ```
40
+
41
+ For `workspaces=<file>`, parse with `jq` (never grep/sed JSON):
42
+
43
+ ```bash
44
+ jq -r 'keys[]' "$WORKSPACES_FILE" \
45
+ | sed "s#^~#$HOME#" \
46
+ | while read -r proj; do
47
+ [ -n "$FILTER" ] && case "$proj" in *"$FILTER"*) : ;; *) continue ;; esac
48
+ [ -f "$proj/.lisa.config.json" ] && echo "$proj"
49
+ done
50
+ ```
51
+
52
+ Skip (and note) any path with no `.lisa.config.json`.
53
+
54
+ ## Step 2 — Load the project's mappings
55
+
56
+ For each project, read `.lisa.config.json`:
57
+
58
+ ```bash
59
+ tracker=$(jq -r '.tracker // "jira"' .lisa.config.json)
60
+ source=$(jq -r '.source // empty' .lisa.config.json)
61
+ ```
62
+
63
+ Resolve the **effective** role → name mapping using the same defaults `/lisa:intake` and `/lisa:setup-jira` use (config-resolution contract). Only keys present in config override the defaults; absent keys fall back to the documented default. Build the list of `(role, configured-name)` pairs to validate:
64
+
65
+ - **JIRA build workflow** (`jira.workflow`): `ready`, `claimed`, optional `review`, `blocked`, and each `done.<env>` (`dev` / `staging` / `production`). Defaults: `Ready`, `In Progress`, `Code Review`, `Blocked`, `{dev: "On Dev", staging: "On Stg", production: "Done"}`.
66
+ - **GitHub build/prd labels** (`github.labels.build`, `github.labels.prd`): each configured label string.
67
+ - **Linear build/prd labels** (`linear.labels.build`, `linear.labels.prd`): each configured label/state string.
68
+ - **Notion PRD values** (`notion.values`): each configured select-option value, validated against the `notion.statusProperty` property's options.
69
+ - **Confluence PRD parents** (`confluence.parents`): each configured parent page id, validated by existence.
70
+
71
+ ## Step 3 — Enumerate the authoritative live name set
72
+
73
+ Resolve the live, canonical names per vendor through the **same access layer the rest of Lisa uses** — never a second source of truth.
74
+
75
+ ### JIRA (via `/lisa:atlassian-access`)
76
+
77
+ First confirm the active substrate is authenticated to **this project's** `atlassian.cloudId` / `atlassian.site`. `/lisa:atlassian-access` already enforces account identity: a substrate authed as a different Atlassian account is skipped, not used. If no substrate matches the configured account, mark the project `UNRESOLVABLE` (auth mismatch) and move on — do **not** validate against the wrong instance, and do **not** trust a case-insensitive JQL pass as proof.
78
+
79
+ Enumerate the project's full workflow status set, preferring the most authoritative substrate:
80
+
81
+ 1. **curl** (authoritative — all statuses, including empty ones):
82
+ ```bash
83
+ # GET /rest/api/3/project/<KEY>/statuses → union of canonical status names across issue types
84
+ # via lisa:atlassian-access curl substrate
85
+ # jq: '[.[].statuses[].name] | unique'
86
+ ```
87
+ 2. **MCP fallback** (when curl creds aren't available): union of `to.name` from `getTransitionsForJiraIssue` (with `includeUnavailableTransitions=true`) on a sample ticket, plus changelog-observed names (`fromString`/`toString`). This can miss a status that is empty *and* unreachable from the sample, so when only this substrate is available, report the enumeration method in the output so the operator knows the set may be partial.
88
+
89
+ > Note: JQL `status = "<name>"` matching is **case-insensitive**, so a JQL probe that "passes" does **not** prove the configured casing matches. Always compare against the canonical `status.name` strings from the enumeration above, case-sensitively.
90
+
91
+ ### GitHub (via `gh`)
92
+
93
+ ```bash
94
+ gh label list --repo "$REPO" --limit 200 --json name -q '.[].name'
95
+ ```
96
+
97
+ ### Linear / Notion / Confluence
98
+
99
+ Enumerate via the corresponding access surface (Linear MCP workflow states + labels; Notion data-source select options for `notion.statusProperty`; Confluence page-exists check per parent id). Same compare-exact-case contract as JIRA.
100
+
101
+ ## Step 4 — Compare (exact case)
102
+
103
+ For each `(role, configured-name)` pair, classify against the live name set:
104
+
105
+ - **VALID** — an exact-case match exists in the live set.
106
+ - **CASE_DRIFT** — a case-insensitive match exists but no exact-case match (e.g. config `"On Stg"` vs live `"ON STG"`). Canonical = the live exact name.
107
+ - **MISSING** — no case-insensitive match exists. The name was renamed beyond recognition or deleted.
108
+
109
+ A project's verdict:
110
+
111
+ - **VALID** — every role is VALID.
112
+ - **DRIFTED** — at least one CASE_DRIFT or MISSING role, none of which is UNRESOLVABLE.
113
+ - **UNRESOLVABLE** — the live set couldn't be enumerated (auth mismatch, missing tracker config, access failure). Distinguish this loudly from VALID — an unresolved audit is not a passing audit.
114
+
115
+ ## Step 5 — Report
116
+
117
+ Per project, print a terminal-first section:
118
+
119
+ ```
120
+ <project-path> [tracker=<vendor> project/repo=<id>] VERDICT
121
+ role configured live (canonical) status
122
+ ready Ready Ready VALID
123
+ claimed In Progress In Progress VALID
124
+ blocked Blocked Blocked VALID
125
+ done.dev On Dev On Dev VALID
126
+ done.staging On Stg ON STG CASE_DRIFT → fix: "ON STG"
127
+ done.production Done Done VALID
128
+ ```
129
+
130
+ End with a roll-up: counts of VALID / DRIFTED / UNRESOLVABLE projects and the exact next command (`… repair=true` when drift is auto-repairable; an admin note when a status is genuinely MISSING).
131
+
132
+ ## Step 6 — Repair (only when `repair=true`)
133
+
134
+ For each drifted role, repair the **config** (preserve everything else; only write changed keys; always `jq … > tmp && mv`):
135
+
136
+ ### CASE_DRIFT — automatic
137
+
138
+ Rewrite the configured value to the live canonical name. Examples:
139
+
140
+ ```bash
141
+ # scalar role (ready/claimed/blocked/review)
142
+ jq --arg v "$CANONICAL" '.jira.workflow.<role> = $v' \
143
+ .lisa.config.json > .lisa.config.json.tmp && mv .lisa.config.json.tmp .lisa.config.json
144
+
145
+ # done.<env>
146
+ jq --arg v "$CANONICAL" '.jira.workflow.done.<env> = $v' \
147
+ .lisa.config.json > .lisa.config.json.tmp && mv .lisa.config.json.tmp .lisa.config.json
148
+
149
+ # github/linear label
150
+ jq --arg v "$CANONICAL" '.github.labels.<lane>.<role> = $v' \
151
+ .lisa.config.json > .lisa.config.json.tmp && mv .lisa.config.json.tmp .lisa.config.json
152
+ ```
153
+
154
+ ### MISSING — confirm first
155
+
156
+ Compute the closest live candidates (case-insensitive token/substring overlap, then edit distance). Present via `AskUserQuestion`:
157
+
158
+ > Role `<role>` maps to `<configured>`, which no longer exists in `<vendor>`. Closest live names: `<c1>`, `<c2>`, `<c3>`. Pick the replacement, leave unchanged, or enter a name manually.
159
+
160
+ Only write on an explicit pick. Never auto-select. If the user leaves it unchanged, keep the project `DRIFTED` and surface the admin remediation (add the status back, or fix it in the tracker).
161
+
162
+ ### Invalidate the verification cache
163
+
164
+ After any JIRA repair, clear the `setup-jira` reachability cache so it re-verifies the new mapping:
165
+
166
+ ```bash
167
+ jq 'if .jira then .jira.verified_workflow_hash = null else . end' \
168
+ .lisa.config.local.json > .lisa.config.local.json.tmp 2>/dev/null \
169
+ && mv .lisa.config.local.json.tmp .lisa.config.local.json || true
170
+ ```
171
+
172
+ Re-print the project section showing the post-repair mapping and the new verdict (VALID if every role now resolves).
173
+
174
+ ## Idempotency & repeatability
175
+
176
+ - Re-running on a clean config reports `VALID` and writes nothing.
177
+ - Read-only mode has no side effects and is safe to schedule. Pair with `/schedule` (or run in CI) to detect drift continuously; run `repair=true` interactively when drift appears (the `MISSING` path needs a human decision and should not run unattended).
178
+ - Repair only ever touches `.lisa.config.json` (and clears the local verification-cache key) — it preserves all unrelated config and never stages secrets or env values.
179
+
180
+ ## Rules
181
+
182
+ - Compare status/label names **case-sensitively** against the live canonical set. A case-insensitive tracker query (e.g. JQL) that resolves is not proof the casing matches.
183
+ - Verify the access substrate is authenticated to the **configured** account before trusting any enumeration. An audit run against the wrong instance is `UNRESOLVABLE`, not `VALID`.
184
+ - Repair fixes the **config**, never the tracker. Do not rename or delete tracker statuses, labels, or options.
185
+ - Never auto-repair a `MISSING` mapping; confirm the replacement via `AskUserQuestion`.
186
+ - Use `jq` for all JSON reads/writes; write only changed keys via `jq … > tmp && mv`.
187
+ - In batch mode, audit each project independently — one project's `UNRESOLVABLE` (e.g. an auth mismatch) must not abort the rest of the sweep.
188
+ - Reuse the config-resolution defaults and the vendor access skills (`atlassian-access`, `gh`, Linear/Notion MCP); do not invent a parallel mapping or lifecycle vocabulary.
@@ -43,11 +43,14 @@ independent and use disjoint name prefixes, so running both is safe.
43
43
  The automation runs **one cycle** of the full wiki ingest and respects that command's own confirmation
44
44
  and commit/PR policy (never ask before running; run a full ingest across every enabled
45
45
  non-external-write source; commit/PR per the ingest skill's bookends; report the cycle summary).
46
- Before running the ingest, the automation must sync its checkout: fetch the default remote branch and
47
- rebase the current automation branch onto it (for the common GitHub case, `origin/main`). If the
48
- checkout is already on the default branch, fast-forward/rebase it to the remote default. If the
49
- rebase has conflicts or the working tree is dirty in a way the automation did not create, abort the
50
- rebase and report the blocker instead of ingesting from stale code.
46
+ Before running the ingest, the automation must attempt to sync its checkout: fetch the default remote
47
+ branch and rebase the current automation branch onto it (for the common GitHub case, `origin/main`).
48
+ If the checkout is already on the default branch, fast-forward/rebase it to the remote default. A
49
+ dirty working tree is not by itself a blocker: capture `git status --short --branch`, leave
50
+ pre-existing changes untouched, and continue when sync and ingest can run without overwriting those
51
+ paths. Abort only when Git reports an actual sync conflict or ingest would need to modify an
52
+ already-dirty path; in that case leave existing queue/wiki state unchanged and report the exact
53
+ conflicting path(s).
51
54
 
52
55
  | Automation | Command it runs | Cadence |
53
56
  |---|---|---|