@codyswann/lisa 3.48.4 → 3.48.5

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 (59) hide show
  1. package/dist/core/upstream-evidence-manifest.js +2 -2
  2. package/package.json +1 -1
  3. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  4. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  5. package/plugins/lisa/.codex-plugin/skills/lisa-setup-github-repo/SKILL.md +1 -0
  6. package/plugins/lisa/skills/lisa-setup-github-repo/SKILL.md +1 -0
  7. package/plugins/lisa-agy/plugin.json +1 -1
  8. package/plugins/lisa-agy/skills/lisa-setup-github-repo/SKILL.md +1 -0
  9. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  10. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  11. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  12. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  13. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  14. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  15. package/plugins/lisa-copilot/skills/lisa-setup-github-repo/SKILL.md +1 -0
  16. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  17. package/plugins/lisa-cursor/skills/lisa-setup-github-repo/SKILL.md +1 -0
  18. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  19. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  20. package/plugins/lisa-expo-agy/plugin.json +1 -1
  21. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  22. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  23. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  24. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  25. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  26. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  27. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  28. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  29. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  30. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  31. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  32. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  33. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  34. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  35. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  36. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  37. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  38. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  39. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  40. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  41. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  42. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  43. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  44. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  45. package/plugins/lisa-rails-agy/plugin.json +1 -1
  46. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  47. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  48. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  49. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  50. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  51. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  52. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  53. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  54. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  55. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  56. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  57. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  58. package/plugins/src/base/skills/lisa-setup-github-repo/SKILL.md +1 -0
  59. package/scripts/lisa-github-rulesets.sh +97 -14
@@ -663,7 +663,7 @@ export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
663
663
  "plugins/src/base/skills/lisa-setup-automations/SKILL.md": "4bf86639bca29641686fd124d7d4b6c177775063930a309e2c33f808e33d505f",
664
664
  "plugins/src/base/skills/lisa-setup-automations/scripts/generate-workflow.mjs": "c13e287c8beb6f847b03c93298b8a3fb211e65ce897e63692933377f8c4303f1",
665
665
  "plugins/src/base/skills/lisa-setup-confluence/SKILL.md": "e92d762dbdaeae671c3e52dfe8e10d40a10b606b5e050589181a3898649faedc",
666
- "plugins/src/base/skills/lisa-setup-github-repo/SKILL.md": "b9b223a5ffad2f88e3fde5831b60fea9bdc2c981750c49d03bb046d43772a0d3",
666
+ "plugins/src/base/skills/lisa-setup-github-repo/SKILL.md": "1e343418a59e54ac1e2b6d542ddbecfa53adb370d6bfe558818d5960f9701bc8",
667
667
  "plugins/src/base/skills/lisa-setup-github/SKILL.md": "75435e81130abd21c678d302b7a220da95a19868d122ca93168278628b200666",
668
668
  "plugins/src/base/skills/lisa-setup-jira/SKILL.md": "261acaeb2923cc9238f468dcf986a0e1323a67e1e51d175b2c1b700dacab2fb8",
669
669
  "plugins/src/base/skills/lisa-setup-kane/SKILL.md": "fe50024a4f896af01716f2435f57227b1f8de61803e80bf3e3c3247ec179b103",
@@ -1113,7 +1113,7 @@ export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
1113
1113
  "scripts/lisa-github-environments.sh": "0a76e92f108519abaf3e29991299ec3b0db20ea533e69e6d2a53d802dba9c370",
1114
1114
  "scripts/lisa-github-repo-settings.sh": "4afbccdfb08c62ba13afee42ec8561a28facf87c61f6f4b80000115328364d54",
1115
1115
  "scripts/lisa-github-repo-setup.sh": "dc2f1c9d718aa34ba57161120d9319b5f78fe6b0b496d8e3c77226a08795aa36",
1116
- "scripts/lisa-github-rulesets.sh": "3e496f8d2d294d68c9f4d156684943dd2c7e35f2aaccf476ea4c7309c3a57b77",
1116
+ "scripts/lisa-github-rulesets.sh": "5899206cb187d877026d7980356a28214dcad4f1d90d855206a95f448900b333",
1117
1117
  "scripts/lisa-mutation.mjs": "74603e61f493d700318feb862f61ee1653430700b5edf232e70241ccdedac587",
1118
1118
  "scripts/lisa-remote-env/session-start.sh": "cb63d08b14ab7aa2d405e6770e0cf7db5d6588ae1dcb924ea6224b026fcff496",
1119
1119
  "scripts/lisa-remote-env/setup.sh": "c30d98a5645f033fc1d3a723043691b9ad997ae5666df539ff6aa19c563431b2",
package/package.json CHANGED
@@ -141,7 +141,7 @@
141
141
  "zod-validation-error": "^4.0.0"
142
142
  },
143
143
  "name": "@codyswann/lisa",
144
- "version": "3.48.4",
144
+ "version": "3.48.5",
145
145
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
146
146
  "main": "dist/index.js",
147
147
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Universal governance: agents, skills, commands, hooks, and rules for all projects.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -28,6 +28,7 @@ Apply the fleet-standard GitHub repository configuration to this project's repo.
28
28
  - `quality checks` — the stack's CI checks (TypeScript emoji names or Rails names)
29
29
  - `prevent delete`, `protect tags` (`v*`), plus stack overlays (`cdk validation`, staging-only `playwright`)
30
30
  - Repos without `.github/workflows/` get only app-based required checks — an Actions check that can never report would block every PR forever
31
+ - **A template change never reaches an already-configured repo on its own** — re-running this step is the migration. Reconciliation is additive (a live-only required context is preserved, never dropped) and legible: each context the run newly makes blocking is printed as `+ now required: <context>`, and a ruleset that already satisfies its template reports `nothing to do` and is not sent at all, so a second run is visibly a no-op
31
32
  3. **Deploy key** (`scripts/setup-deploy-key.sh --yes`) — write-access deploy key + `DEPLOY_KEY` secret, skipped when already configured. The `base` ruleset's `DeployKey: always` bypass is what lets CI version-bump pushes through protected branches.
32
33
  4. **Deployment environments** (`scripts/lisa-github-environments.sh`) — entirely optional; only runs when `.lisa.config.json` declares environments:
33
34
  ```json
@@ -28,6 +28,7 @@ Apply the fleet-standard GitHub repository configuration to this project's repo.
28
28
  - `quality checks` — the stack's CI checks (TypeScript emoji names or Rails names)
29
29
  - `prevent delete`, `protect tags` (`v*`), plus stack overlays (`cdk validation`, staging-only `playwright`)
30
30
  - Repos without `.github/workflows/` get only app-based required checks — an Actions check that can never report would block every PR forever
31
+ - **A template change never reaches an already-configured repo on its own** — re-running this step is the migration. Reconciliation is additive (a live-only required context is preserved, never dropped) and legible: each context the run newly makes blocking is printed as `+ now required: <context>`, and a ruleset that already satisfies its template reports `nothing to do` and is not sent at all, so a second run is visibly a no-op
31
32
  3. **Deploy key** (`scripts/setup-deploy-key.sh --yes`) — write-access deploy key + `DEPLOY_KEY` secret, skipped when already configured. The `base` ruleset's `DeployKey: always` bypass is what lets CI version-bump pushes through protected branches.
32
33
  4. **Deployment environments** (`scripts/lisa-github-environments.sh`) — entirely optional; only runs when `.lisa.config.json` declares environments:
33
34
  ```json
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -28,6 +28,7 @@ Apply the fleet-standard GitHub repository configuration to this project's repo.
28
28
  - `quality checks` — the stack's CI checks (TypeScript emoji names or Rails names)
29
29
  - `prevent delete`, `protect tags` (`v*`), plus stack overlays (`cdk validation`, staging-only `playwright`)
30
30
  - Repos without `.github/workflows/` get only app-based required checks — an Actions check that can never report would block every PR forever
31
+ - **A template change never reaches an already-configured repo on its own** — re-running this step is the migration. Reconciliation is additive (a live-only required context is preserved, never dropped) and legible: each context the run newly makes blocking is printed as `+ now required: <context>`, and a ruleset that already satisfies its template reports `nothing to do` and is not sent at all, so a second run is visibly a no-op
31
32
  3. **Deploy key** (`scripts/setup-deploy-key.sh --yes`) — write-access deploy key + `DEPLOY_KEY` secret, skipped when already configured. The `base` ruleset's `DeployKey: always` bypass is what lets CI version-bump pushes through protected branches.
32
33
  4. **Deployment environments** (`scripts/lisa-github-environments.sh`) — entirely optional; only runs when `.lisa.config.json` declares environments:
33
34
  ```json
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "AWS CDK-specific Lisa plugin.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -28,6 +28,7 @@ Apply the fleet-standard GitHub repository configuration to this project's repo.
28
28
  - `quality checks` — the stack's CI checks (TypeScript emoji names or Rails names)
29
29
  - `prevent delete`, `protect tags` (`v*`), plus stack overlays (`cdk validation`, staging-only `playwright`)
30
30
  - Repos without `.github/workflows/` get only app-based required checks — an Actions check that can never report would block every PR forever
31
+ - **A template change never reaches an already-configured repo on its own** — re-running this step is the migration. Reconciliation is additive (a live-only required context is preserved, never dropped) and legible: each context the run newly makes blocking is printed as `+ now required: <context>`, and a ruleset that already satisfies its template reports `nothing to do` and is not sent at all, so a second run is visibly a no-op
31
32
  3. **Deploy key** (`scripts/setup-deploy-key.sh --yes`) — write-access deploy key + `DEPLOY_KEY` secret, skipped when already configured. The `base` ruleset's `DeployKey: always` bypass is what lets CI version-bump pushes through protected branches.
32
33
  4. **Deployment environments** (`scripts/lisa-github-environments.sh`) — entirely optional; only runs when `.lisa.config.json` declares environments:
33
34
  ```json
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -28,6 +28,7 @@ Apply the fleet-standard GitHub repository configuration to this project's repo.
28
28
  - `quality checks` — the stack's CI checks (TypeScript emoji names or Rails names)
29
29
  - `prevent delete`, `protect tags` (`v*`), plus stack overlays (`cdk validation`, staging-only `playwright`)
30
30
  - Repos without `.github/workflows/` get only app-based required checks — an Actions check that can never report would block every PR forever
31
+ - **A template change never reaches an already-configured repo on its own** — re-running this step is the migration. Reconciliation is additive (a live-only required context is preserved, never dropped) and legible: each context the run newly makes blocking is printed as `+ now required: <context>`, and a ruleset that already satisfies its template reports `nothing to do` and is not sent at all, so a second run is visibly a no-op
31
32
  3. **Deploy key** (`scripts/setup-deploy-key.sh --yes`) — write-access deploy key + `DEPLOY_KEY` secret, skipped when already configured. The `base` ruleset's `DeployKey: always` bypass is what lets CI version-bump pushes through protected branches.
32
33
  4. **Deployment environments** (`scripts/lisa-github-environments.sh`) — entirely optional; only runs when `.lisa.config.json` declares environments:
33
34
  ```json
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Expo and React Native-specific skills, agents, rules, and MCP servers.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Harper/Fabric-specific Lisa rules for TypeScript component apps.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "NestJS-specific skills and migration write-protection hooks.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
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": "3.48.4",
3
+ "version": "3.48.5",
4
4
  "description": "Ruby on Rails-specific skills and hooks for RuboCop 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": "3.48.4",
3
+ "version": "3.48.5",
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": "3.48.4",
3
+ "version": "3.48.5",
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": "3.48.4",
3
+ "version": "3.48.5",
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": "3.48.4",
3
+ "version": "3.48.5",
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": "3.48.4",
3
+ "version": "3.48.5",
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": "3.48.4",
3
+ "version": "3.48.5",
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": "3.48.4",
3
+ "version": "3.48.5",
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": "3.48.4",
3
+ "version": "3.48.5",
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": "3.48.4",
3
+ "version": "3.48.5",
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": "3.48.4",
3
+ "version": "3.48.5",
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"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "3.48.4",
3
+ "version": "3.48.5",
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": "3.48.4",
3
+ "version": "3.48.5",
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": "3.48.4",
3
+ "version": "3.48.5",
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"
@@ -28,6 +28,7 @@ Apply the fleet-standard GitHub repository configuration to this project's repo.
28
28
  - `quality checks` — the stack's CI checks (TypeScript emoji names or Rails names)
29
29
  - `prevent delete`, `protect tags` (`v*`), plus stack overlays (`cdk validation`, staging-only `playwright`)
30
30
  - Repos without `.github/workflows/` get only app-based required checks — an Actions check that can never report would block every PR forever
31
+ - **A template change never reaches an already-configured repo on its own** — re-running this step is the migration. Reconciliation is additive (a live-only required context is preserved, never dropped) and legible: each context the run newly makes blocking is printed as `+ now required: <context>`, and a ruleset that already satisfies its template reports `nothing to do` and is not sent at all, so a second run is visibly a no-op
31
32
  3. **Deploy key** (`scripts/setup-deploy-key.sh --yes`) — write-access deploy key + `DEPLOY_KEY` secret, skipped when already configured. The `base` ruleset's `DeployKey: always` bypass is what lets CI version-bump pushes through protected branches.
32
33
  4. **Deployment environments** (`scripts/lisa-github-environments.sh`) — entirely optional; only runs when `.lisa.config.json` declares environments:
33
34
  ```json
@@ -39,6 +39,11 @@ YES_MODE=false
39
39
  VERBOSE=false
40
40
  PROJECT_PATH=""
41
41
 
42
+ # Rulesets that already matched and were therefore not sent, and the payload
43
+ # GitHub last accepted (set by apply_with_integration_fallback).
44
+ UNCHANGED_COUNT=0
45
+ APPLIED_PAYLOAD=""
46
+
42
47
  # Project type hierarchy (child -> parent)
43
48
  # Using a function to avoid associative array issues with set -u
44
49
  get_parent_type() {
@@ -428,22 +433,14 @@ add_config_required_checks() {
428
433
  }
429
434
 
430
435
  preserve_live_required_checks() {
431
- local repo="$1"
432
- local existing_id="$2"
433
- local json="$3"
434
- local ruleset_name="$4"
436
+ local live="$1"
437
+ local json="$2"
435
438
 
436
- if [[ -z "$existing_id" ]]; then
439
+ if [[ -z "$live" ]]; then
437
440
  echo "$json"
438
441
  return 0
439
442
  fi
440
443
 
441
- local live
442
- if ! live=$(gh api -X GET "repos/$repo/rulesets/$existing_id" 2>/dev/null); then
443
- log_warning "Could not read existing ruleset '$ruleset_name' details — refusing to silently replace required checks" >&2
444
- return 1
445
- fi
446
-
447
444
  echo "$json" | jq --argjson live "$live" '
448
445
  def required_checks:
449
446
  (.rules // [])
@@ -475,6 +472,73 @@ preserve_live_required_checks() {
475
472
  end'
476
473
  }
477
474
 
475
+ # The contexts the outgoing payload requires that the live ruleset does not.
476
+ # This is the drift a template change opens: a context added to a template never
477
+ # reaches an already-configured repository on its own (#2641), so the operator
478
+ # needs the reconciliation to SAY which checks it just made blocking rather than
479
+ # to report an opaque "applied".
480
+ ruleset_added_contexts() {
481
+ local live="$1"
482
+ local payload="$2"
483
+
484
+ jq -r -n --argjson live "${live:-null}" --argjson want "$payload" '
485
+ def contexts:
486
+ [ (.rules // [])[]
487
+ | select(.type == "required_status_checks")
488
+ | (.parameters.required_status_checks // [])[]
489
+ | .context ];
490
+
491
+ (if $live == null then [] else ($live | contexts) end) as $have
492
+ | ($want | contexts)
493
+ | map(select(. as $context | ($have | index($context)) | not))
494
+ | .[]'
495
+ }
496
+
497
+ # True when everything the payload asks for is ALREADY true of the live ruleset.
498
+ #
499
+ # Deliberately a subset test rather than an equality test: GitHub echoes back
500
+ # parameters it filled in with its own defaults (`required_reviewers`,
501
+ # `require_extra_approval_for_unattributed_changes`, ...) which no template
502
+ # names. Comparing whole documents would report drift on every run and make
503
+ # "nothing to do" unreachable — the AC's second scenario would then never hold
504
+ # even on a repository that needs no change.
505
+ ruleset_is_current() {
506
+ local live="$1"
507
+ local payload="$2"
508
+
509
+ [[ -n "$live" ]] || return 1
510
+
511
+ jq -e -n \
512
+ --argjson live "$(strip_readonly_fields "$live")" \
513
+ --argjson want "$payload" '
514
+ def covers($have; $need):
515
+ if ($need | type) == "object" then
516
+ ($have | type) == "object"
517
+ and ([$need | keys_unsorted[]]
518
+ | all(. as $key | ($have | has($key)) and covers($have[$key]; $need[$key])))
519
+ elif ($need | type) == "array" then
520
+ ($have | type) == "array"
521
+ and ($have | length) == ($need | length)
522
+ and ([range(0; $need | length)]
523
+ | all(. as $index | covers($have[$index]; $need[$index])))
524
+ else $have == $need
525
+ end;
526
+ covers($live; $want)' > /dev/null
527
+ }
528
+
529
+ # Print one line per context this run makes blocking. Reads the payload that
530
+ # GitHub actually ACCEPTED, so a context dropped by the integration fallback is
531
+ # never reported as added.
532
+ report_added_contexts() {
533
+ local live="$1"
534
+ local payload="$2"
535
+
536
+ local context
537
+ while IFS= read -r context; do
538
+ [[ -n "$context" ]] && log_info " + now required: $context"
539
+ done < <(ruleset_added_contexts "$live" "$payload")
540
+ }
541
+
478
542
  apply_ruleset() {
479
543
  local repo="$1"
480
544
  local template_file="$2"
@@ -499,10 +563,22 @@ apply_ruleset() {
499
563
  return 0
500
564
  fi
501
565
 
502
- local existing_id
566
+ local existing_id live=""
503
567
  existing_id=$(find_ruleset_by_name "$existing_rulesets" "$ruleset_name")
504
568
  if [[ -n "$existing_id" ]]; then
505
- clean_template=$(preserve_live_required_checks "$repo" "$existing_id" "$clean_template" "$ruleset_name")
569
+ if ! live=$(gh api -X GET "repos/$repo/rulesets/$existing_id" 2>/dev/null); then
570
+ log_warning "Could not read existing ruleset '$ruleset_name' details — refusing to silently replace required checks"
571
+ return 1
572
+ fi
573
+ clean_template=$(preserve_live_required_checks "$live" "$clean_template")
574
+ fi
575
+
576
+ # Idempotence: a run that would change nothing must say so and send nothing,
577
+ # so a second run is visibly a no-op rather than an indistinguishable write.
578
+ if ruleset_is_current "$live" "$clean_template"; then
579
+ log_success "Ruleset '$ruleset_name' already matches the template — nothing to do"
580
+ UNCHANGED_COUNT=$((UNCHANGED_COUNT + 1))
581
+ return 0
506
582
  fi
507
583
 
508
584
  if [[ "$DRY_RUN" == "true" ]]; then
@@ -511,6 +587,7 @@ apply_ruleset() {
511
587
  else
512
588
  log_info "[DRY RUN] Would create ruleset '$ruleset_name'"
513
589
  fi
590
+ report_added_contexts "$live" "$clean_template"
514
591
  log_verbose "Template: $template_file"
515
592
  return 0
516
593
  fi
@@ -521,7 +598,9 @@ apply_ruleset() {
521
598
  log_info "Creating ruleset '$ruleset_name'..."
522
599
  fi
523
600
 
601
+ APPLIED_PAYLOAD=""
524
602
  if apply_with_integration_fallback "$repo" "$ruleset_name" "$clean_template" "$existing_id"; then
603
+ report_added_contexts "$live" "${APPLIED_PAYLOAD:-$clean_template}"
525
604
  return 0
526
605
  fi
527
606
  log_error "Failed to apply ruleset '$ruleset_name'"
@@ -546,6 +625,7 @@ apply_with_integration_fallback() {
546
625
  # Capture stdout AND stderr — gh prints the API error body (which carries
547
626
  # the "Invalid integration ids" detail) on stdout, not stderr.
548
627
  send_ruleset() {
628
+ APPLIED_PAYLOAD="$1"
549
629
  echo "$1" > "$temp_file"
550
630
  if [[ -n "$existing_id" ]]; then
551
631
  error_output=$(gh api -X PUT "repos/$repo/rulesets/$existing_id" --input "$temp_file" 2>&1)
@@ -772,7 +852,10 @@ main() {
772
852
  if [[ "$DRY_RUN" == "true" ]]; then
773
853
  log_info "Dry run complete. ${#templates[@]} ruleset(s) would be applied."
774
854
  else
775
- log_success "Applied $success_count ruleset(s)"
855
+ log_success "Applied $((success_count - UNCHANGED_COUNT)) ruleset(s), $UNCHANGED_COUNT already current"
856
+ if [[ $UNCHANGED_COUNT -eq $success_count ]]; then
857
+ log_info "Nothing to do — every ruleset already matches its template"
858
+ fi
776
859
  if [[ $fail_count -gt 0 ]]; then
777
860
  log_warning "$fail_count ruleset(s) failed"
778
861
  exit 1