@codyswann/lisa 4.74.9 → 4.75.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.
- package/.claude-plugin/marketplace.json +60 -0
- package/all/copy-overwrite/scripts/lib/npm-update-github.mjs +73 -40
- package/all/copy-overwrite/scripts/lib/npm-update-invariants.mjs +54 -0
- package/all/copy-overwrite/scripts/npm-updater-helper-graph.json +3 -2
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +6 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/lisa-skill-sources.d.ts +3 -3
- package/dist/core/lisa-skill-sources.d.ts.map +1 -1
- package/dist/core/lisa-skill-sources.js +3 -2
- package/dist/core/lisa-skill-sources.js.map +1 -1
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +735 -8
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/package.json +4 -4
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-devin/.claude-plugin/plugin.json +11 -0
- package/plugins/lisa-cdk-devin/.devin-plugin/plugin.json +8 -0
- package/plugins/lisa-cdk-devin/skills/setup-aws-accounts/SKILL.md +292 -0
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-devin/.claude-plugin/plugin.json +8 -0
- package/plugins/lisa-devin/.devin-plugin/plugin.json +8 -0
- package/plugins/lisa-devin/.mcp.json +8 -0
- package/plugins/lisa-devin/agents/architecture-specialist.md +32 -0
- package/plugins/lisa-devin/agents/bug-fixer.md +43 -0
- package/plugins/lisa-devin/agents/builder.md +44 -0
- package/plugins/lisa-devin/agents/confluence-prd-intake.md +65 -0
- package/plugins/lisa-devin/agents/debug-specialist.md +34 -0
- package/plugins/lisa-devin/agents/eval-specialist.md +33 -0
- package/plugins/lisa-devin/agents/git-history-analyzer.md +183 -0
- package/plugins/lisa-devin/agents/github-agent.md +155 -0
- package/plugins/lisa-devin/agents/github-build-intake.md +64 -0
- package/plugins/lisa-devin/agents/github-prd-intake.md +66 -0
- package/plugins/lisa-devin/agents/jira-agent.md +135 -0
- package/plugins/lisa-devin/agents/jira-build-intake.md +64 -0
- package/plugins/lisa-devin/agents/learner.md +85 -0
- package/plugins/lisa-devin/agents/learning-judge.md +119 -0
- package/plugins/lisa-devin/agents/learnings-synthesizer.md +155 -0
- package/plugins/lisa-devin/agents/linear-agent.md +138 -0
- package/plugins/lisa-devin/agents/linear-build-intake.md +64 -0
- package/plugins/lisa-devin/agents/linear-prd-intake.md +66 -0
- package/plugins/lisa-devin/agents/notion-prd-intake.md +63 -0
- package/plugins/lisa-devin/agents/performance-specialist.md +26 -0
- package/plugins/lisa-devin/agents/pr-mining-specialist.md +85 -0
- package/plugins/lisa-devin/agents/product-specialist.md +30 -0
- package/plugins/lisa-devin/agents/quality-specialist.md +30 -0
- package/plugins/lisa-devin/agents/security-specialist.md +43 -0
- package/plugins/lisa-devin/agents/skill-evaluator.md +205 -0
- package/plugins/lisa-devin/agents/spec-conformance-specialist.md +56 -0
- package/plugins/lisa-devin/agents/test-specialist.md +32 -0
- package/plugins/lisa-devin/agents/tracker-mining-specialist.md +85 -0
- package/plugins/lisa-devin/agents/verification-specialist.md +145 -0
- package/plugins/lisa-devin/hooks/auto-update.mjs +824 -0
- package/plugins/lisa-devin/hooks/auto-update.sh +31 -0
- package/plugins/lisa-devin/hooks/block-blind-automerge.sh +1242 -0
- package/plugins/lisa-devin/hooks/block-direct-issue-create.sh +2603 -0
- package/plugins/lisa-devin/hooks/block-host-name-leak.mjs +412 -0
- package/plugins/lisa-devin/hooks/block-host-name-leak.sh +61 -0
- package/plugins/lisa-devin/hooks/block-instruction-file-edits.sh +207 -0
- package/plugins/lisa-devin/hooks/block-managed-file-edits.sh +1175 -0
- package/plugins/lisa-devin/hooks/block-no-verify.sh +2288 -0
- package/plugins/lisa-devin/hooks/block-shell-json-parsing.sh +263 -0
- package/plugins/lisa-devin/hooks/cleanup-stale-worktrees.sh +122 -0
- package/plugins/lisa-devin/hooks/devin-tool-name-shim.sh +30 -0
- package/plugins/lisa-devin/hooks/discharge-work-item-gates.sh +90 -0
- package/plugins/lisa-devin/hooks/enforce-verification-gate.sh +506 -0
- package/plugins/lisa-devin/hooks/enforcement-vintage-npm.mjs +320 -0
- package/plugins/lisa-devin/hooks/enforcement-vintage.mjs +472 -0
- package/plugins/lisa-devin/hooks/enforcement-vintage.sh +48 -0
- package/plugins/lisa-devin/hooks/failure-signature-index.mjs +717 -0
- package/plugins/lisa-devin/hooks/failure-signature-index.sh +26 -0
- package/plugins/lisa-devin/hooks/guard-dedupe.bash +374 -0
- package/plugins/lisa-devin/hooks/inject-resolved-config.mjs +903 -0
- package/plugins/lisa-devin/hooks/inject-resolved-config.sh +107 -0
- package/plugins/lisa-devin/hooks/inject-rules.sh +49 -0
- package/plugins/lisa-devin/hooks/install-pkgs.sh +84 -0
- package/plugins/lisa-devin/hooks/operational-hazards.mjs +736 -0
- package/plugins/lisa-devin/hooks/operational-hazards.sh +28 -0
- package/plugins/lisa-devin/hooks/parity-safety-net-heredoc.py +1004 -0
- package/plugins/lisa-devin/hooks/parity-safety-net.sh +3275 -0
- package/plugins/lisa-devin/hooks/secrets-preflight.sh +72 -0
- package/plugins/lisa-devin/hooks/setup-jira-cli.sh +205 -0
- package/plugins/lisa-devin/hooks/shell-write-nudge.sh +86 -0
- package/plugins/lisa-devin/hooks/sonar-secrets.sh +205 -0
- package/plugins/lisa-devin/hooks/threshold-ratchet-compare.mjs +518 -0
- package/plugins/lisa-devin/hooks/threshold-ratchet-families.mjs +543 -0
- package/plugins/lisa-devin/hooks/threshold-ratchet.mjs +568 -0
- package/plugins/lisa-devin/hooks/threshold-ratchet.sh +22 -0
- package/plugins/lisa-devin/hooks/withdrawn-rulings.mjs +600 -0
- package/plugins/lisa-devin/hooks/withdrawn-rulings.sh +24 -0
- package/plugins/lisa-devin/hooks/worktree-binding-guard.mjs +1383 -0
- package/plugins/lisa-devin/hooks/worktree-binding-guard.sh +79 -0
- package/plugins/lisa-devin/hooks.json +247 -0
- package/plugins/lisa-devin/rules/eager/00-rule-index.md +82 -0
- package/plugins/lisa-devin/rules/eager/base-rules.md +85 -0
- package/plugins/lisa-devin/rules/eager/coding-philosophy.md +27 -0
- package/plugins/lisa-devin/rules/eager/config-resolution.md +37 -0
- package/plugins/lisa-devin/rules/eager/do-it-now.md +11 -0
- package/plugins/lisa-devin/rules/eager/empirical-inquiry.md +24 -0
- package/plugins/lisa-devin/rules/eager/falsifiable-checks.md +48 -0
- package/plugins/lisa-devin/rules/eager/history-audit.md +27 -0
- package/plugins/lisa-devin/rules/eager/integration-access-layer.md +19 -0
- package/plugins/lisa-devin/rules/eager/intent-routing.md +18 -0
- package/plugins/lisa-devin/rules/eager/learnings-ladder.md +18 -0
- package/plugins/lisa-devin/rules/eager/local-ci-first.md +15 -0
- package/plugins/lisa-devin/rules/eager/measurement-integrity.md +18 -0
- package/plugins/lisa-devin/rules/eager/never-name-a-downstream-project.md +9 -0
- package/plugins/lisa-devin/rules/eager/not-blocked-just-waiting.md +13 -0
- package/plugins/lisa-devin/rules/eager/operational-hazards.md +50 -0
- package/plugins/lisa-devin/rules/eager/report-actionability.md +26 -0
- package/plugins/lisa-devin/rules/eager/security-audit-handling.md +40 -0
- package/plugins/lisa-devin/rules/eager/session-status-updates.md +20 -0
- package/plugins/lisa-devin/rules/eager/settled-decisions.md +75 -0
- package/plugins/lisa-devin/rules/eager/stale-state-claims.md +26 -0
- package/plugins/lisa-devin/rules/eager/tool-access-gate.md +23 -0
- package/plugins/lisa-devin/rules/eager/tracked-work.md +9 -0
- package/plugins/lisa-devin/rules/eager/upstream-to-lisa.md +14 -0
- package/plugins/lisa-devin/rules/eager/verification.md +33 -0
- package/plugins/lisa-devin/rules/eager/wiki-knowledge-source.md +13 -0
- package/plugins/lisa-devin/rules/eager/withdrawn-rulings.md +102 -0
- package/plugins/lisa-devin/rules/reference/automation-runbook-contract.md +355 -0
- package/plugins/lisa-devin/rules/reference/base-rules.md +136 -0
- package/plugins/lisa-devin/rules/reference/bdd-e2e-coverage.md +301 -0
- package/plugins/lisa-devin/rules/reference/blocker-containment.md +165 -0
- package/plugins/lisa-devin/rules/reference/claim-archaeology.md +184 -0
- package/plugins/lisa-devin/rules/reference/claim-evidence-mapping.md +362 -0
- package/plugins/lisa-devin/rules/reference/claim-time-guards.md +135 -0
- package/plugins/lisa-devin/rules/reference/coding-philosophy.md +428 -0
- package/plugins/lisa-devin/rules/reference/config-resolution.md +1225 -0
- package/plugins/lisa-devin/rules/reference/control-reachability.md +166 -0
- package/plugins/lisa-devin/rules/reference/convergent-review.md +145 -0
- package/plugins/lisa-devin/rules/reference/credential-substrate-precedence.md +249 -0
- package/plugins/lisa-devin/rules/reference/dependency-decision-records.md +177 -0
- package/plugins/lisa-devin/rules/reference/dependency-internalization-kit.md +244 -0
- package/plugins/lisa-devin/rules/reference/dependency-trust-classes.md +291 -0
- package/plugins/lisa-devin/rules/reference/deployed-state-readback.md +142 -0
- package/plugins/lisa-devin/rules/reference/derived-branch-plan.md +214 -0
- package/plugins/lisa-devin/rules/reference/design-source-of-truth.md +260 -0
- package/plugins/lisa-devin/rules/reference/design-value-binding.md +311 -0
- package/plugins/lisa-devin/rules/reference/do-it-now.md +19 -0
- package/plugins/lisa-devin/rules/reference/documentation-source-paths.md +31 -0
- package/plugins/lisa-devin/rules/reference/empirical-inquiry.md +28 -0
- package/plugins/lisa-devin/rules/reference/factory-model.md +111 -0
- package/plugins/lisa-devin/rules/reference/falsifiable-checks.md +275 -0
- package/plugins/lisa-devin/rules/reference/history-audit.md +42 -0
- package/plugins/lisa-devin/rules/reference/integration-access-layer.md +89 -0
- package/plugins/lisa-devin/rules/reference/intent-routing.md +428 -0
- package/plugins/lisa-devin/rules/reference/leaf-only-lifecycle.md +227 -0
- package/plugins/lisa-devin/rules/reference/learnings-ladder.md +41 -0
- package/plugins/lisa-devin/rules/reference/local-ci-first.md +34 -0
- package/plugins/lisa-devin/rules/reference/measurement-integrity.md +119 -0
- package/plugins/lisa-devin/rules/reference/never-name-a-downstream-project.md +37 -0
- package/plugins/lisa-devin/rules/reference/not-blocked-just-waiting.md +41 -0
- package/plugins/lisa-devin/rules/reference/observability-audit.md +146 -0
- package/plugins/lisa-devin/rules/reference/operational-hazards.md +115 -0
- package/plugins/lisa-devin/rules/reference/prd-definition-of-ready.md +118 -0
- package/plugins/lisa-devin/rules/reference/prd-lifecycle-rollup.md +192 -0
- package/plugins/lisa-devin/rules/reference/pre-flight-autofill.md +250 -0
- package/plugins/lisa-devin/rules/reference/project-learnings.md +159 -0
- package/plugins/lisa-devin/rules/reference/promotion-contract.md +148 -0
- package/plugins/lisa-devin/rules/reference/readiness-rubric.md +242 -0
- package/plugins/lisa-devin/rules/reference/ready-role-filing.md +212 -0
- package/plugins/lisa-devin/rules/reference/rejection-detection.md +308 -0
- package/plugins/lisa-devin/rules/reference/repo-scope-split.md +119 -0
- package/plugins/lisa-devin/rules/reference/report-actionability.md +61 -0
- package/plugins/lisa-devin/rules/reference/reset-seed-coverage.md +286 -0
- package/plugins/lisa-devin/rules/reference/security-audit-handling.md +55 -0
- package/plugins/lisa-devin/rules/reference/session-status-updates.md +111 -0
- package/plugins/lisa-devin/rules/reference/settled-decisions.md +39 -0
- package/plugins/lisa-devin/rules/reference/stale-state-claims.md +88 -0
- package/plugins/lisa-devin/rules/reference/tool-access-gate.md +114 -0
- package/plugins/lisa-devin/rules/reference/tracked-work.md +49 -0
- package/plugins/lisa-devin/rules/reference/upstream-to-lisa.md +26 -0
- package/plugins/lisa-devin/rules/reference/usage-accounting.md +261 -0
- package/plugins/lisa-devin/rules/reference/verification.md +278 -0
- package/plugins/lisa-devin/rules/reference/wiki-knowledge-source.md +37 -0
- package/plugins/lisa-devin/rules/reference/withdrawn-rulings.md +148 -0
- package/plugins/lisa-devin/rules/reference/work-item-definition-of-ready.md +177 -0
- package/plugins/lisa-devin/rules/reference/work-item-trailer-definition.md +129 -0
- package/plugins/lisa-devin/scripts/automation-run-record.mjs +678 -0
- package/plugins/lisa-devin/scripts/automation-status-claude-adapter.mjs +804 -0
- package/plugins/lisa-devin/scripts/automation-status-codex-adapter.mjs +1081 -0
- package/plugins/lisa-devin/scripts/automation-status-contract-drift.mjs +392 -0
- package/plugins/lisa-devin/scripts/automation-status-expected-fleet.mjs +508 -0
- package/plugins/lisa-devin/scripts/automation-status-report.mjs +200 -0
- package/plugins/lisa-devin/scripts/automation-status-run-history.mjs +216 -0
- package/plugins/lisa-devin/scripts/automation-status-unrecorded-runs.mjs +127 -0
- package/plugins/lisa-devin/scripts/blocker-edge-resolution.mjs +150 -0
- package/plugins/lisa-devin/scripts/cross-pollinate.mjs +763 -0
- package/plugins/lisa-devin/scripts/design-bindings-probe.mjs +713 -0
- package/plugins/lisa-devin/scripts/design-intake-gate.mjs +470 -0
- package/plugins/lisa-devin/scripts/design-source-gate.mjs +610 -0
- package/plugins/lisa-devin/scripts/design-variable-ids.mjs +567 -0
- package/plugins/lisa-devin/scripts/doctor-report.mjs +635 -0
- package/plugins/lisa-devin/scripts/install-remote-agent-aws.mjs +443 -0
- package/plugins/lisa-devin/scripts/intake-blocker-reprobe.mjs +1065 -0
- package/plugins/lisa-devin/scripts/intake-prework-denominator.mjs +249 -0
- package/plugins/lisa-devin/scripts/lifecycle-label-trust.mjs +593 -0
- package/plugins/lisa-devin/scripts/linear-state-write-target.mjs +362 -0
- package/plugins/lisa-devin/scripts/plugin-sync-explain.mjs +654 -0
- package/plugins/lisa-devin/scripts/pr-arming-sweep.mjs +561 -0
- package/plugins/lisa-devin/scripts/project-ideation-idempotency-harness.mjs +338 -0
- package/plugins/lisa-devin/scripts/qa-signal-lifecycle.mjs +523 -0
- package/plugins/lisa-devin/scripts/queue-contract-resolution.mjs +583 -0
- package/plugins/lisa-devin/scripts/queue-health-classification.mjs +157 -0
- package/plugins/lisa-devin/scripts/queue-status-build-readers.mjs +561 -0
- package/plugins/lisa-devin/scripts/queue-status-prd-readers.mjs +452 -0
- package/plugins/lisa-devin/scripts/remote-agent-aws-setup.sh +677 -0
- package/plugins/lisa-devin/scripts/repo-scope-vocabulary-audit.mjs +458 -0
- package/plugins/lisa-devin/scripts/resolve-lifecycle-role.mjs +347 -0
- package/plugins/lisa-devin/scripts/rollup-blocker-classification.mjs +616 -0
- package/plugins/lisa-devin/scripts/scoping-label-audit.mjs +474 -0
- package/plugins/lisa-devin/skills/lisa-acceptance-criteria/SKILL.md +73 -0
- package/plugins/lisa-devin/skills/lisa-agent-design-best-practices/SKILL.md +242 -0
- package/plugins/lisa-devin/skills/lisa-agent-ready/SKILL.md +271 -0
- package/plugins/lisa-devin/skills/lisa-analyze-claude-remote/SKILL.md +434 -0
- package/plugins/lisa-devin/skills/lisa-atlassian-access/SKILL.md +469 -0
- package/plugins/lisa-devin/skills/lisa-atlassian-access/scripts/markdown-to-adf.mjs +236 -0
- package/plugins/lisa-devin/skills/lisa-attribute-failure/SKILL.md +142 -0
- package/plugins/lisa-devin/skills/lisa-automation-status/SKILL.md +149 -0
- package/plugins/lisa-devin/skills/lisa-bug-triage/SKILL.md +23 -0
- package/plugins/lisa-devin/skills/lisa-capability-drift/SKILL.md +71 -0
- package/plugins/lisa-devin/skills/lisa-codebase-research/SKILL.md +87 -0
- package/plugins/lisa-devin/skills/lisa-codify-verification/SKILL.md +213 -0
- package/plugins/lisa-devin/skills/lisa-confluence-prd-intake/SKILL.md +417 -0
- package/plugins/lisa-devin/skills/lisa-confluence-to-tracker/SKILL.md +469 -0
- package/plugins/lisa-devin/skills/lisa-confluence-write-prd/SKILL.md +111 -0
- package/plugins/lisa-devin/skills/lisa-cross-pollinate/SKILL.md +175 -0
- package/plugins/lisa-devin/skills/lisa-debrief/SKILL.md +96 -0
- package/plugins/lisa-devin/skills/lisa-debrief-apply/SKILL.md +106 -0
- package/plugins/lisa-devin/skills/lisa-delivery-effectiveness/SKILL.md +62 -0
- package/plugins/lisa-devin/skills/lisa-design-intake/SKILL.md +198 -0
- package/plugins/lisa-devin/skills/lisa-detect-tooling/SKILL.md +110 -0
- package/plugins/lisa-devin/skills/lisa-detect-tooling/scripts/commands.mjs +479 -0
- package/plugins/lisa-devin/skills/lisa-detect-tooling/scripts/detect-tooling.mjs +658 -0
- package/plugins/lisa-devin/skills/lisa-doctor/SKILL.md +743 -0
- package/plugins/lisa-devin/skills/lisa-drive-pr-to-merge/SKILL.md +1587 -0
- package/plugins/lisa-devin/skills/lisa-epic-triage/SKILL.md +28 -0
- package/plugins/lisa-devin/skills/lisa-evaluation-suite/SKILL.md +63 -0
- package/plugins/lisa-devin/skills/lisa-exploratory-qa/SKILL.md +185 -0
- package/plugins/lisa-devin/skills/lisa-fix-linter-error/SKILL.md +45 -0
- package/plugins/lisa-devin/skills/lisa-generate-claude-remote-build-script/SKILL.md +235 -0
- package/plugins/lisa-devin/skills/lisa-git-commit/SKILL.md +53 -0
- package/plugins/lisa-devin/skills/lisa-git-prune/SKILL.md +35 -0
- package/plugins/lisa-devin/skills/lisa-git-submit-pr/SKILL.md +170 -0
- package/plugins/lisa-devin/skills/lisa-github-add-journey/SKILL.md +118 -0
- package/plugins/lisa-devin/skills/lisa-github-build-intake/SKILL.md +745 -0
- package/plugins/lisa-devin/skills/lisa-github-claim/SKILL.md +27 -0
- package/plugins/lisa-devin/skills/lisa-github-create/SKILL.md +105 -0
- package/plugins/lisa-devin/skills/lisa-github-evidence/SKILL.md +120 -0
- package/plugins/lisa-devin/skills/lisa-github-journey/SKILL.md +134 -0
- package/plugins/lisa-devin/skills/lisa-github-prd-intake/SKILL.md +424 -0
- package/plugins/lisa-devin/skills/lisa-github-project-v2/SKILL.md +227 -0
- package/plugins/lisa-devin/skills/lisa-github-read-issue/SKILL.md +305 -0
- package/plugins/lisa-devin/skills/lisa-github-sync/SKILL.md +201 -0
- package/plugins/lisa-devin/skills/lisa-github-to-tracker/SKILL.md +456 -0
- package/plugins/lisa-devin/skills/lisa-github-validate-issue/SKILL.md +598 -0
- package/plugins/lisa-devin/skills/lisa-github-verify/SKILL.md +60 -0
- package/plugins/lisa-devin/skills/lisa-github-write-issue/SKILL.md +531 -0
- package/plugins/lisa-devin/skills/lisa-github-write-prd/SKILL.md +156 -0
- package/plugins/lisa-devin/skills/lisa-health/SKILL.md +142 -0
- package/plugins/lisa-devin/skills/lisa-health-drift-cron/SKILL.md +80 -0
- package/plugins/lisa-devin/skills/lisa-implement/SKILL.md +372 -0
- package/plugins/lisa-devin/skills/lisa-improve-code-complexity/SKILL.md +44 -0
- package/plugins/lisa-devin/skills/lisa-improve-harness/SKILL.md +487 -0
- package/plugins/lisa-devin/skills/lisa-improve-max-lines/SKILL.md +45 -0
- package/plugins/lisa-devin/skills/lisa-improve-max-lines-per-function/SKILL.md +46 -0
- package/plugins/lisa-devin/skills/lisa-improve-test-coverage/SKILL.md +47 -0
- package/plugins/lisa-devin/skills/lisa-improve-tests/SKILL.md +50 -0
- package/plugins/lisa-devin/skills/lisa-intake/SKILL.md +208 -0
- package/plugins/lisa-devin/skills/lisa-intake-explain/SKILL.md +279 -0
- package/plugins/lisa-devin/skills/lisa-jam-access/SKILL.md +128 -0
- package/plugins/lisa-devin/skills/lisa-jira-add-journey/SKILL.md +139 -0
- package/plugins/lisa-devin/skills/lisa-jira-build-intake/SKILL.md +556 -0
- package/plugins/lisa-devin/skills/lisa-jira-claim/SKILL.md +27 -0
- package/plugins/lisa-devin/skills/lisa-jira-create/SKILL.md +157 -0
- package/plugins/lisa-devin/skills/lisa-jira-evidence/SKILL.md +106 -0
- package/plugins/lisa-devin/skills/lisa-jira-evidence/scripts/post-evidence.sh +262 -0
- package/plugins/lisa-devin/skills/lisa-jira-journey/SKILL.md +168 -0
- package/plugins/lisa-devin/skills/lisa-jira-journey/scripts/generate-templates.py +239 -0
- package/plugins/lisa-devin/skills/lisa-jira-journey/scripts/parse-plan.py +570 -0
- package/plugins/lisa-devin/skills/lisa-jira-read-ticket/SKILL.md +199 -0
- package/plugins/lisa-devin/skills/lisa-jira-read-ticket/scripts/download-attachment.sh +211 -0
- package/plugins/lisa-devin/skills/lisa-jira-sync/SKILL.md +117 -0
- package/plugins/lisa-devin/skills/lisa-jira-validate-ticket/SKILL.md +525 -0
- package/plugins/lisa-devin/skills/lisa-jira-verify/SKILL.md +61 -0
- package/plugins/lisa-devin/skills/lisa-jira-write-ticket/SKILL.md +440 -0
- package/plugins/lisa-devin/skills/lisa-jsdoc-best-practices/SKILL.md +491 -0
- package/plugins/lisa-devin/skills/lisa-kane-browser/SKILL.md +80 -0
- package/plugins/lisa-devin/skills/lisa-learnings-audit/SKILL.md +490 -0
- package/plugins/lisa-devin/skills/lisa-linear-access/SKILL.md +483 -0
- package/plugins/lisa-devin/skills/lisa-linear-add-journey/SKILL.md +109 -0
- package/plugins/lisa-devin/skills/lisa-linear-build-intake/SKILL.md +548 -0
- package/plugins/lisa-devin/skills/lisa-linear-claim/SKILL.md +28 -0
- package/plugins/lisa-devin/skills/lisa-linear-create/SKILL.md +150 -0
- package/plugins/lisa-devin/skills/lisa-linear-evidence/SKILL.md +124 -0
- package/plugins/lisa-devin/skills/lisa-linear-journey/SKILL.md +147 -0
- package/plugins/lisa-devin/skills/lisa-linear-prd-intake/SKILL.md +411 -0
- package/plugins/lisa-devin/skills/lisa-linear-read-issue/SKILL.md +201 -0
- package/plugins/lisa-devin/skills/lisa-linear-sync/SKILL.md +164 -0
- package/plugins/lisa-devin/skills/lisa-linear-to-tracker/SKILL.md +454 -0
- package/plugins/lisa-devin/skills/lisa-linear-validate-issue/SKILL.md +504 -0
- package/plugins/lisa-devin/skills/lisa-linear-verify/SKILL.md +65 -0
- package/plugins/lisa-devin/skills/lisa-linear-write-issue/SKILL.md +448 -0
- package/plugins/lisa-devin/skills/lisa-linear-write-prd/SKILL.md +98 -0
- package/plugins/lisa-devin/skills/lisa-monitor/SKILL.md +224 -0
- package/plugins/lisa-devin/skills/lisa-nightly-add-test-coverage/SKILL.md +40 -0
- package/plugins/lisa-devin/skills/lisa-nightly-improve-tests/SKILL.md +29 -0
- package/plugins/lisa-devin/skills/lisa-nightly-lower-code-complexity/SKILL.md +42 -0
- package/plugins/lisa-devin/skills/lisa-notion-access/SKILL.md +301 -0
- package/plugins/lisa-devin/skills/lisa-notion-prd-intake/SKILL.md +360 -0
- package/plugins/lisa-devin/skills/lisa-notion-to-tracker/SKILL.md +467 -0
- package/plugins/lisa-devin/skills/lisa-notion-write-prd/SKILL.md +111 -0
- package/plugins/lisa-devin/skills/lisa-parity-code-review/SKILL.md +83 -0
- package/plugins/lisa-devin/skills/lisa-parity-code-simplifier/SKILL.md +76 -0
- package/plugins/lisa-devin/skills/lisa-parity-coderabbit/SKILL.md +87 -0
- package/plugins/lisa-devin/skills/lisa-parity-sentry-sdk-setup/SKILL.md +375 -0
- package/plugins/lisa-devin/skills/lisa-parity-sentry-seer/SKILL.md +168 -0
- package/plugins/lisa-devin/skills/lisa-parity-skill-creator/SKILL.md +155 -0
- package/plugins/lisa-devin/skills/lisa-performance-review/SKILL.md +94 -0
- package/plugins/lisa-devin/skills/lisa-persist-learning/SKILL.md +247 -0
- package/plugins/lisa-devin/skills/lisa-plan/SKILL.md +64 -0
- package/plugins/lisa-devin/skills/lisa-plugin-sync-explain/SKILL.md +53 -0
- package/plugins/lisa-devin/skills/lisa-posthog-access/SKILL.md +140 -0
- package/plugins/lisa-devin/skills/lisa-prd-backlink/SKILL.md +274 -0
- package/plugins/lisa-devin/skills/lisa-prd-source-write/SKILL.md +104 -0
- package/plugins/lisa-devin/skills/lisa-prd-ticket-coverage/SKILL.md +187 -0
- package/plugins/lisa-devin/skills/lisa-product-walkthrough/SKILL.md +106 -0
- package/plugins/lisa-devin/skills/lisa-project-ideation/SKILL.md +417 -0
- package/plugins/lisa-devin/skills/lisa-project-ideation/examples/evidence-card-format.md +21 -0
- package/plugins/lisa-devin/skills/lisa-project-ideation/examples/host-project-only.md +22 -0
- package/plugins/lisa-devin/skills/lisa-project-ideation/examples/idempotency-verification-harness.md +57 -0
- package/plugins/lisa-devin/skills/lisa-project-ideation/examples/public-external-inspiration.md +22 -0
- package/plugins/lisa-devin/skills/lisa-project-ideation/examples/unavailable-data-rejection.md +22 -0
- package/plugins/lisa-devin/skills/lisa-pull-request-review/SKILL.md +132 -0
- package/plugins/lisa-devin/skills/lisa-quality-review/SKILL.md +63 -0
- package/plugins/lisa-devin/skills/lisa-queue-status/SKILL.md +215 -0
- package/plugins/lisa-devin/skills/lisa-remote-dispatch/SKILL.md +109 -0
- package/plugins/lisa-devin/skills/lisa-remote-dispatch/scripts/dispatch.mjs +535 -0
- package/plugins/lisa-devin/skills/lisa-repair-intake/SKILL.md +1621 -0
- package/plugins/lisa-devin/skills/lisa-reproduce-bug/SKILL.md +75 -0
- package/plugins/lisa-devin/skills/lisa-research/SKILL.md +92 -0
- package/plugins/lisa-devin/skills/lisa-review-implementation/SKILL.md +209 -0
- package/plugins/lisa-devin/skills/lisa-review-local/SKILL.md +141 -0
- package/plugins/lisa-devin/skills/lisa-rework-triage/SKILL.md +206 -0
- package/plugins/lisa-devin/skills/lisa-root-cause-analysis/SKILL.md +135 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/SKILL.md +430 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/aws-bootstrap.mjs +433 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/bootstrap-store.mjs +288 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/doctor-secrets.mjs +273 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/envfile.mjs +80 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/inspect-vault.mjs +142 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/materialize-secrets.mjs +1085 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/note-format.mjs +179 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/owner.mjs +96 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/preflight-secrets.mjs +342 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/prompt-secret.mjs +79 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/providers.mjs +805 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/publish-aws-bootstrap.mjs +680 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/read-secret-note.mjs +105 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/resolve-expo-token.mjs +90 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/resolve-secret.mjs +285 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/rotate-secret.mjs +297 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/routing-floor.mjs +153 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/surfaces.mjs +480 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/sync-secret-to-ci.mjs +510 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/tools-from-notes.mjs +63 -0
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/validate-config.mjs +550 -0
- package/plugins/lisa-devin/skills/lisa-security-review/SKILL.md +124 -0
- package/plugins/lisa-devin/skills/lisa-security-zap-scan/SKILL.md +53 -0
- package/plugins/lisa-devin/skills/lisa-sentry-access/SKILL.md +140 -0
- package/plugins/lisa-devin/skills/lisa-setup-atlassian/SKILL.md +407 -0
- package/plugins/lisa-devin/skills/lisa-setup-automations/SKILL.md +430 -0
- package/plugins/lisa-devin/skills/lisa-setup-automations/scripts/generate-workflow.mjs +288 -0
- package/plugins/lisa-devin/skills/lisa-setup-confluence/SKILL.md +254 -0
- package/plugins/lisa-devin/skills/lisa-setup-github/SKILL.md +319 -0
- package/plugins/lisa-devin/skills/lisa-setup-github-repo/SKILL.md +128 -0
- package/plugins/lisa-devin/skills/lisa-setup-jira/SKILL.md +198 -0
- package/plugins/lisa-devin/skills/lisa-setup-kane/SKILL.md +96 -0
- package/plugins/lisa-devin/skills/lisa-setup-linear/SKILL.md +375 -0
- package/plugins/lisa-devin/skills/lisa-setup-local-env/SKILL.md +95 -0
- package/plugins/lisa-devin/skills/lisa-setup-local-env/scripts/local-env.mjs +196 -0
- package/plugins/lisa-devin/skills/lisa-setup-notion/SKILL.md +376 -0
- package/plugins/lisa-devin/skills/lisa-setup-remote-aws/SKILL.md +149 -0
- package/plugins/lisa-devin/skills/lisa-setup-remote-env/SKILL.md +382 -0
- package/plugins/lisa-devin/skills/lisa-setup-remote-env/assets/materialized-env-authority.mjs +262 -0
- package/plugins/lisa-devin/skills/lisa-setup-remote-env/assets/session-start.sh +87 -0
- package/plugins/lisa-devin/skills/lisa-setup-remote-env/assets/setup.sh +216 -0
- package/plugins/lisa-devin/skills/lisa-setup-remote-env/scripts/environment.mjs +227 -0
- package/plugins/lisa-devin/skills/lisa-setup-remote-env/scripts/preflight-tools.mjs +378 -0
- package/plugins/lisa-devin/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +1632 -0
- package/plugins/lisa-devin/skills/lisa-setup-remote-env/scripts/tool-floor.mjs +94 -0
- package/plugins/lisa-devin/skills/lisa-setup-remote-env/scripts/toolchain.mjs +448 -0
- package/plugins/lisa-devin/skills/lisa-setup-remote-env/scripts/verify-remote-env.mjs +250 -0
- package/plugins/lisa-devin/skills/lisa-setup-sonar/SKILL.md +153 -0
- package/plugins/lisa-devin/skills/lisa-setup-workstation/SKILL.md +143 -0
- package/plugins/lisa-devin/skills/lisa-setup-workstation/scripts/bounded-child.mjs +168 -0
- package/plugins/lisa-devin/skills/lisa-setup-workstation/scripts/catalogue.mjs +293 -0
- package/plugins/lisa-devin/skills/lisa-setup-workstation/scripts/cli.mjs +333 -0
- package/plugins/lisa-devin/skills/lisa-setup-workstation/scripts/workstation.mjs +511 -0
- package/plugins/lisa-devin/skills/lisa-sonarcloud-access/SKILL.md +202 -0
- package/plugins/lisa-devin/skills/lisa-spec-conformance/SKILL.md +205 -0
- package/plugins/lisa-devin/skills/lisa-starter-sync/SKILL.md +35 -0
- package/plugins/lisa-devin/skills/lisa-sync-down/SKILL.md +209 -0
- package/plugins/lisa-devin/skills/lisa-task-decomposition/SKILL.md +195 -0
- package/plugins/lisa-devin/skills/lisa-task-triage/SKILL.md +23 -0
- package/plugins/lisa-devin/skills/lisa-tdd-implementation/SKILL.md +91 -0
- package/plugins/lisa-devin/skills/lisa-tear-down-automations/SKILL.md +85 -0
- package/plugins/lisa-devin/skills/lisa-test-strategy/SKILL.md +66 -0
- package/plugins/lisa-devin/skills/lisa-ticket-triage/SKILL.md +214 -0
- package/plugins/lisa-devin/skills/lisa-track/SKILL.md +129 -0
- package/plugins/lisa-devin/skills/lisa-tracker-add-journey/SKILL.md +28 -0
- package/plugins/lisa-devin/skills/lisa-tracker-build-intake/SKILL.md +134 -0
- package/plugins/lisa-devin/skills/lisa-tracker-claim/SKILL.md +35 -0
- package/plugins/lisa-devin/skills/lisa-tracker-create/SKILL.md +28 -0
- package/plugins/lisa-devin/skills/lisa-tracker-evidence/SKILL.md +63 -0
- package/plugins/lisa-devin/skills/lisa-tracker-journey/SKILL.md +27 -0
- package/plugins/lisa-devin/skills/lisa-tracker-read/SKILL.md +28 -0
- package/plugins/lisa-devin/skills/lisa-tracker-source-artifacts/SKILL.md +111 -0
- package/plugins/lisa-devin/skills/lisa-tracker-sync/SKILL.md +150 -0
- package/plugins/lisa-devin/skills/lisa-tracker-validate/SKILL.md +37 -0
- package/plugins/lisa-devin/skills/lisa-tracker-verify/SKILL.md +29 -0
- package/plugins/lisa-devin/skills/lisa-tracker-write/SKILL.md +55 -0
- package/plugins/lisa-devin/skills/lisa-usage-accounting/SKILL.md +205 -0
- package/plugins/lisa-devin/skills/lisa-usage-accounting/references/effectiveness.md +63 -0
- package/plugins/lisa-devin/skills/lisa-use-the-product/SKILL.md +86 -0
- package/plugins/lisa-devin/skills/lisa-validate-tracker-mapping/SKILL.md +467 -0
- package/plugins/lisa-devin/skills/lisa-verification-lifecycle/SKILL.md +384 -0
- package/plugins/lisa-devin/skills/lisa-verify/SKILL.md +55 -0
- package/plugins/lisa-devin/skills/lisa-verify-prd/SKILL.md +394 -0
- package/plugins/lisa-devin/skills/lisa-verify-workflow-change/SKILL.md +154 -0
- package/plugins/lisa-devin/skills/lisa-wiki-install/SKILL.md +101 -0
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-devin/.claude-plugin/plugin.json +11 -0
- package/plugins/lisa-expo-devin/.devin-plugin/plugin.json +8 -0
- package/plugins/lisa-expo-devin/.mcp.json +8 -0
- package/plugins/lisa-expo-devin/THIRD-PARTY-NOTICES.md +84 -0
- package/plugins/lisa-expo-devin/agents/ops-specialist.md +124 -0
- package/plugins/lisa-expo-devin/hooks/devin-tool-name-shim.sh +30 -0
- package/plugins/lisa-expo-devin/hooks/register-maestro-mcp.sh +84 -0
- package/plugins/lisa-expo-devin/hooks.json +14 -0
- package/plugins/lisa-expo-devin/skills/add-app-clip/SKILL.md +280 -0
- package/plugins/lisa-expo-devin/skills/add-app-clip/references/native-module.md +96 -0
- package/plugins/lisa-expo-devin/skills/apollo-client/SKILL.md +238 -0
- package/plugins/lisa-expo-devin/skills/apollo-client/references/mutation-patterns.md +360 -0
- package/plugins/lisa-expo-devin/skills/atomic-design-gluestack/SKILL.md +369 -0
- package/plugins/lisa-expo-devin/skills/atomic-design-gluestack/references/atomic-levels.md +417 -0
- package/plugins/lisa-expo-devin/skills/atomic-design-gluestack/references/folder-structure.md +257 -0
- package/plugins/lisa-expo-devin/skills/atomic-design-gluestack/references/gluestack-mapping.md +233 -0
- package/plugins/lisa-expo-devin/skills/atomic-design-gluestack/scripts/test_validate_atomic_structure.py +240 -0
- package/plugins/lisa-expo-devin/skills/atomic-design-gluestack/scripts/validate_atomic_structure.py +438 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/SKILL.md +321 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/animations.md +220 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/controls.md +272 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/form-sheet.md +253 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/gradients.md +106 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/icons.md +213 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/media.md +198 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/route-structure.md +229 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/search.md +248 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/storage.md +121 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/tabs.md +433 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/toolbar-and-headers.md +284 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/visual-effects.md +197 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/webgpu-three.md +605 -0
- package/plugins/lisa-expo-devin/skills/building-native-ui/references/zoom-transitions.md +158 -0
- package/plugins/lisa-expo-devin/skills/container-view-pattern/SKILL.md +355 -0
- package/plugins/lisa-expo-devin/skills/container-view-pattern/references/examples.md +749 -0
- package/plugins/lisa-expo-devin/skills/container-view-pattern/references/patterns.md +318 -0
- package/plugins/lisa-expo-devin/skills/container-view-pattern/scripts/create_component.py +200 -0
- package/plugins/lisa-expo-devin/skills/container-view-pattern/scripts/validate_component.py +332 -0
- package/plugins/lisa-expo-devin/skills/cross-platform-compatibility/SKILL.md +268 -0
- package/plugins/lisa-expo-devin/skills/cross-platform-compatibility/references/common-issues.md +619 -0
- package/plugins/lisa-expo-devin/skills/cross-platform-compatibility/references/file-extensions.md +340 -0
- package/plugins/lisa-expo-devin/skills/cross-platform-compatibility/references/platform-api.md +276 -0
- package/plugins/lisa-expo-devin/skills/cross-platform-compatibility/scripts/validate_cross_platform.py +416 -0
- package/plugins/lisa-expo-devin/skills/directory-structure/SKILL.md +214 -0
- package/plugins/lisa-expo-devin/skills/directory-structure/scripts/validate_structure.py +454 -0
- package/plugins/lisa-expo-devin/skills/e2e-coverage-gaps/SKILL.md +117 -0
- package/plugins/lisa-expo-devin/skills/eas-update-insights/SKILL.md +228 -0
- package/plugins/lisa-expo-devin/skills/eas-update-insights/references/channel-insights-schema.md +47 -0
- package/plugins/lisa-expo-devin/skills/eas-update-insights/references/update-insights-schema.md +69 -0
- package/plugins/lisa-expo-devin/skills/expo-api-routes/SKILL.md +369 -0
- package/plugins/lisa-expo-devin/skills/expo-brownfield/SKILL.md +54 -0
- package/plugins/lisa-expo-devin/skills/expo-brownfield/references/brownfield-integrated.md +526 -0
- package/plugins/lisa-expo-devin/skills/expo-brownfield/references/brownfield-isolated.md +402 -0
- package/plugins/lisa-expo-devin/skills/expo-brownfield/references/comparison.md +63 -0
- package/plugins/lisa-expo-devin/skills/expo-brownfield/references/troubleshooting.md +88 -0
- package/plugins/lisa-expo-devin/skills/expo-cicd-workflows/SKILL.md +92 -0
- package/plugins/lisa-expo-devin/skills/expo-cicd-workflows/scripts/fetch.js +113 -0
- package/plugins/lisa-expo-devin/skills/expo-cicd-workflows/scripts/package.json +11 -0
- package/plugins/lisa-expo-devin/skills/expo-cicd-workflows/scripts/validate.js +85 -0
- package/plugins/lisa-expo-devin/skills/expo-deployment/SKILL.md +193 -0
- package/plugins/lisa-expo-devin/skills/expo-deployment/references/app-store-metadata.md +479 -0
- package/plugins/lisa-expo-devin/skills/expo-deployment/references/ios-app-store.md +355 -0
- package/plugins/lisa-expo-devin/skills/expo-deployment/references/play-store.md +264 -0
- package/plugins/lisa-expo-devin/skills/expo-deployment/references/testflight.md +58 -0
- package/plugins/lisa-expo-devin/skills/expo-deployment/references/workflows.md +200 -0
- package/plugins/lisa-expo-devin/skills/expo-dev-client/SKILL.md +164 -0
- package/plugins/lisa-expo-devin/skills/expo-env-config/SKILL.md +309 -0
- package/plugins/lisa-expo-devin/skills/expo-env-config/references/validation-patterns.md +417 -0
- package/plugins/lisa-expo-devin/skills/expo-module/SKILL.md +141 -0
- package/plugins/lisa-expo-devin/skills/expo-module/references/config-plugin.md +90 -0
- package/plugins/lisa-expo-devin/skills/expo-module/references/create-expo-module.md +206 -0
- package/plugins/lisa-expo-devin/skills/expo-module/references/lifecycle.md +127 -0
- package/plugins/lisa-expo-devin/skills/expo-module/references/module-config.md +48 -0
- package/plugins/lisa-expo-devin/skills/expo-module/references/native-module.md +286 -0
- package/plugins/lisa-expo-devin/skills/expo-module/references/native-view.md +171 -0
- package/plugins/lisa-expo-devin/skills/expo-router-best-practices/SKILL.md +432 -0
- package/plugins/lisa-expo-devin/skills/expo-router-best-practices/references/official-docs.md +290 -0
- package/plugins/lisa-expo-devin/skills/expo-router-best-practices/references/static-export-verification.md +54 -0
- package/plugins/lisa-expo-devin/skills/expo-router-best-practices/scripts/generate-route.py +171 -0
- package/plugins/lisa-expo-devin/skills/expo-tailwind-setup/SKILL.md +487 -0
- package/plugins/lisa-expo-devin/skills/expo-ui-jetpack-compose/SKILL.md +40 -0
- package/plugins/lisa-expo-devin/skills/expo-ui-swift-ui/SKILL.md +39 -0
- package/plugins/lisa-expo-devin/skills/gluestack-nativewind/SKILL.md +419 -0
- package/plugins/lisa-expo-devin/skills/gluestack-nativewind/references/color-tokens.md +343 -0
- package/plugins/lisa-expo-devin/skills/gluestack-nativewind/references/component-mapping.md +307 -0
- package/plugins/lisa-expo-devin/skills/gluestack-nativewind/references/spacing-scale.md +300 -0
- package/plugins/lisa-expo-devin/skills/gluestack-nativewind/scripts/test_validate_styling.py +240 -0
- package/plugins/lisa-expo-devin/skills/gluestack-nativewind/scripts/validate_styling.py +424 -0
- package/plugins/lisa-expo-devin/skills/jira-add-journey/SKILL.md +140 -0
- package/plugins/lisa-expo-devin/skills/jira-create/SKILL.md +161 -0
- package/plugins/lisa-expo-devin/skills/jira-evidence/SKILL.md +84 -0
- package/plugins/lisa-expo-devin/skills/jira-evidence/scripts/post-evidence.sh +262 -0
- package/plugins/lisa-expo-devin/skills/jira-journey/SKILL.md +196 -0
- package/plugins/lisa-expo-devin/skills/jira-journey/scripts/generate-templates.py +281 -0
- package/plugins/lisa-expo-devin/skills/jira-journey/scripts/parse-plan.py +400 -0
- package/plugins/lisa-expo-devin/skills/jira-verify/SKILL.md +27 -0
- package/plugins/lisa-expo-devin/skills/local-state/SKILL.md +362 -0
- package/plugins/lisa-expo-devin/skills/local-state/references/async-storage.md +505 -0
- package/plugins/lisa-expo-devin/skills/local-state/references/persistence-patterns.md +711 -0
- package/plugins/lisa-expo-devin/skills/local-state/references/reactive-variables.md +446 -0
- package/plugins/lisa-expo-devin/skills/maestro-mcp-setup/SKILL.md +144 -0
- package/plugins/lisa-expo-devin/skills/native-data-fetching/SKILL.md +507 -0
- package/plugins/lisa-expo-devin/skills/native-data-fetching/references/expo-router-loaders.md +344 -0
- package/plugins/lisa-expo-devin/skills/ops-browser-uat/SKILL.md +124 -0
- package/plugins/lisa-expo-devin/skills/ops-check-logs/SKILL.md +217 -0
- package/plugins/lisa-expo-devin/skills/ops-db-ops/SKILL.md +214 -0
- package/plugins/lisa-expo-devin/skills/ops-deploy/SKILL.md +123 -0
- package/plugins/lisa-expo-devin/skills/ops-monitor-errors/SKILL.md +99 -0
- package/plugins/lisa-expo-devin/skills/ops-performance/SKILL.md +165 -0
- package/plugins/lisa-expo-devin/skills/ops-run-local/SKILL.md +169 -0
- package/plugins/lisa-expo-devin/skills/ops-verify-health/SKILL.md +101 -0
- package/plugins/lisa-expo-devin/skills/owasp-zap/SKILL.md +61 -0
- package/plugins/lisa-expo-devin/skills/play-store-access/SKILL.md +226 -0
- package/plugins/lisa-expo-devin/skills/playwright-ci-debugging/SKILL.md +140 -0
- package/plugins/lisa-expo-devin/skills/playwright-selectors/SKILL.md +496 -0
- package/plugins/lisa-expo-devin/skills/reduce-complexity/SKILL.md +251 -0
- package/plugins/lisa-expo-devin/skills/reduce-complexity/references/extraction-strategies.md +456 -0
- package/plugins/lisa-expo-devin/skills/reduce-complexity/references/refactoring-patterns.md +557 -0
- package/plugins/lisa-expo-devin/skills/testing-library/SKILL.md +314 -0
- package/plugins/lisa-expo-devin/skills/testing-library/references/async-patterns.md +420 -0
- package/plugins/lisa-expo-devin/skills/testing-library/references/expo-router-testing.md +556 -0
- package/plugins/lisa-expo-devin/skills/testing-library/references/mocking-patterns.md +612 -0
- package/plugins/lisa-expo-devin/skills/testing-library/references/query-priority.md +291 -0
- package/plugins/lisa-expo-devin/skills/upgrading-expo/SKILL.md +134 -0
- package/plugins/lisa-expo-devin/skills/upgrading-expo/references/expo-av-to-audio.md +132 -0
- package/plugins/lisa-expo-devin/skills/upgrading-expo/references/expo-av-to-video.md +160 -0
- package/plugins/lisa-expo-devin/skills/upgrading-expo/references/native-tabs.md +124 -0
- package/plugins/lisa-expo-devin/skills/upgrading-expo/references/new-architecture.md +79 -0
- package/plugins/lisa-expo-devin/skills/upgrading-expo/references/react-19.md +79 -0
- package/plugins/lisa-expo-devin/skills/upgrading-expo/references/react-compiler.md +59 -0
- package/plugins/lisa-expo-devin/skills/upgrading-expo/references/react-navigation-to-expo-router.md +61 -0
- package/plugins/lisa-expo-devin/skills/use-dom/SKILL.md +417 -0
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-devin/.claude-plugin/plugin.json +11 -0
- package/plugins/lisa-harper-fabric-devin/.devin-plugin/plugin.json +8 -0
- package/plugins/lisa-harper-fabric-devin/generated-artifact-globs.txt +5 -0
- package/plugins/lisa-harper-fabric-devin/hooks/block-generated-artifact-edits.sh +141 -0
- package/plugins/lisa-harper-fabric-devin/hooks/devin-tool-name-shim.sh +30 -0
- package/plugins/lisa-harper-fabric-devin/hooks/enforce-config-extensions.mjs +196 -0
- package/plugins/lisa-harper-fabric-devin/hooks/enforce-config-extensions.sh +46 -0
- package/plugins/lisa-harper-fabric-devin/hooks/inject-rules.sh +27 -0
- package/plugins/lisa-harper-fabric-devin/hooks.json +36 -0
- package/plugins/lisa-harper-fabric-devin/rules/eager/harper-fabric.md +31 -0
- package/plugins/lisa-harper-fabric-devin/rules/reference/harper-fabric.md +52 -0
- package/plugins/lisa-harper-fabric-devin/skills/e2e-coverage-gaps/SKILL.md +117 -0
- package/plugins/lisa-harper-fabric-devin/skills/harper-auth/SKILL.md +368 -0
- package/plugins/lisa-harper-fabric-devin/skills/harper-build-and-deploy/SKILL.md +198 -0
- package/plugins/lisa-harper-fabric-devin/skills/harper-caching/SKILL.md +265 -0
- package/plugins/lisa-harper-fabric-devin/skills/harper-component-model/SKILL.md +87 -0
- package/plugins/lisa-harper-fabric-devin/skills/harper-config-yaml/SKILL.md +283 -0
- package/plugins/lisa-harper-fabric-devin/skills/harper-operations/SKILL.md +239 -0
- package/plugins/lisa-harper-fabric-devin/skills/harper-realtime/SKILL.md +187 -0
- package/plugins/lisa-harper-fabric-devin/skills/harper-resources/SKILL.md +142 -0
- package/plugins/lisa-harper-fabric-devin/skills/harper-rest-queries/SKILL.md +403 -0
- package/plugins/lisa-harper-fabric-devin/skills/harper-schema-graphql/SKILL.md +123 -0
- package/plugins/lisa-harper-fabric-devin/skills/harper-testing/SKILL.md +254 -0
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-devin/.claude-plugin/plugin.json +11 -0
- package/plugins/lisa-nestjs-devin/.devin-plugin/plugin.json +8 -0
- package/plugins/lisa-nestjs-devin/hooks/block-migration-edits.sh +125 -0
- package/plugins/lisa-nestjs-devin/hooks/devin-tool-name-shim.sh +30 -0
- package/plugins/lisa-nestjs-devin/hooks/lisa-edit-gate.sh +152 -0
- package/plugins/lisa-nestjs-devin/hooks.json +15 -0
- package/plugins/lisa-nestjs-devin/skills/nestjs-graphql/SKILL.md +176 -0
- package/plugins/lisa-nestjs-devin/skills/nestjs-graphql/references/advanced-features.md +527 -0
- package/plugins/lisa-nestjs-devin/skills/nestjs-graphql/references/project-patterns.md +531 -0
- package/plugins/lisa-nestjs-devin/skills/nestjs-graphql/references/quick-start.md +257 -0
- package/plugins/lisa-nestjs-devin/skills/nestjs-graphql/references/resolvers-mutations.md +413 -0
- package/plugins/lisa-nestjs-devin/skills/nestjs-graphql/references/types-scalars.md +513 -0
- package/plugins/lisa-nestjs-devin/skills/nestjs-rules/SKILL.md +560 -0
- package/plugins/lisa-nestjs-devin/skills/typeorm-patterns/SKILL.md +275 -0
- package/plugins/lisa-nestjs-devin/skills/typeorm-patterns/references/configuration-patterns.md +487 -0
- package/plugins/lisa-nestjs-devin/skills/typeorm-patterns/references/entity-patterns.md +450 -0
- package/plugins/lisa-nestjs-devin/skills/typeorm-patterns/references/observability-patterns.md +536 -0
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-devin/.claude-plugin/plugin.json +8 -0
- package/plugins/lisa-openclaw-devin/.devin-plugin/plugin.json +8 -0
- package/plugins/lisa-openclaw-devin/skills/lisa-openclaw-connect-repo-topic/SKILL.md +163 -0
- package/plugins/lisa-openclaw-devin/skills/lisa-openclaw-connect-repo-topic/references/repo-topic-config.md +185 -0
- package/plugins/lisa-openclaw-devin/skills/lisa-openclaw-connect-staff/SKILL.md +175 -0
- package/plugins/lisa-openclaw-devin/skills/lisa-openclaw-connect-staff/references/platform-routing.md +123 -0
- package/plugins/lisa-openclaw-devin/skills/lisa-openclaw-connect-staff/references/prompts.md +78 -0
- package/plugins/lisa-openclaw-devin/skills/lisa-openclaw-setup/SKILL.md +141 -0
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-devin/.claude-plugin/plugin.json +11 -0
- package/plugins/lisa-phaser-devin/.devin-plugin/plugin.json +8 -0
- package/plugins/lisa-phaser-devin/agents/accessibility-advocate.md +55 -0
- package/plugins/lisa-phaser-devin/agents/art-director.md +90 -0
- package/plugins/lisa-phaser-devin/agents/audio-director.md +65 -0
- package/plugins/lisa-phaser-devin/agents/combat-designer.md +61 -0
- package/plugins/lisa-phaser-devin/agents/economy-designer.md +59 -0
- package/plugins/lisa-phaser-devin/agents/game-designer.md +62 -0
- package/plugins/lisa-phaser-devin/agents/game-feel-specialist.md +56 -0
- package/plugins/lisa-phaser-devin/agents/level-designer.md +59 -0
- package/plugins/lisa-phaser-devin/agents/localization-manager.md +61 -0
- package/plugins/lisa-phaser-devin/agents/marketing-strategist.md +59 -0
- package/plugins/lisa-phaser-devin/agents/monetization-designer.md +59 -0
- package/plugins/lisa-phaser-devin/agents/narrative-designer.md +56 -0
- package/plugins/lisa-phaser-devin/agents/onboarding-advocate.md +59 -0
- package/plugins/lisa-phaser-devin/agents/player-advocate.md +57 -0
- package/plugins/lisa-phaser-devin/agents/producer.md +61 -0
- package/plugins/lisa-phaser-devin/agents/product-analyst.md +62 -0
- package/plugins/lisa-phaser-devin/agents/publisher.md +59 -0
- package/plugins/lisa-phaser-devin/agents/qa-playtester.md +57 -0
- package/plugins/lisa-phaser-devin/agents/target-player.md +52 -0
- package/plugins/lisa-phaser-devin/agents/ux-ui-designer.md +60 -0
- package/plugins/lisa-phaser-devin/hooks/devin-tool-name-shim.sh +30 -0
- package/plugins/lisa-phaser-devin/hooks/inject-rules.sh +27 -0
- package/plugins/lisa-phaser-devin/hooks.json +14 -0
- package/plugins/lisa-phaser-devin/rules/eager/phaser.md +44 -0
- package/plugins/lisa-phaser-devin/rules/reference/phaser.md +184 -0
- package/plugins/lisa-phaser-devin/skills/phaser-accessibility/SKILL.md +135 -0
- package/plugins/lisa-phaser-devin/skills/phaser-asset-pipeline/SKILL.md +222 -0
- package/plugins/lisa-phaser-devin/skills/phaser-asset-sourcing/SKILL.md +151 -0
- package/plugins/lisa-phaser-devin/skills/phaser-build-deploy/SKILL.md +153 -0
- package/plugins/lisa-phaser-devin/skills/phaser-i18n/SKILL.md +122 -0
- package/plugins/lisa-phaser-devin/skills/phaser-project-structure/SKILL.md +89 -0
- package/plugins/lisa-phaser-devin/skills/phaser-services/SKILL.md +208 -0
- package/plugins/lisa-phaser-devin/skills/phaser-testing/SKILL.md +192 -0
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-devin/.claude-plugin/plugin.json +11 -0
- package/plugins/lisa-rails-devin/.devin-plugin/plugin.json +8 -0
- package/plugins/lisa-rails-devin/agents/ops-specialist.md +226 -0
- package/plugins/lisa-rails-devin/hooks/devin-tool-name-shim.sh +30 -0
- package/plugins/lisa-rails-devin/hooks/inject-rules.sh +40 -0
- package/plugins/lisa-rails-devin/hooks/lisa-edit-gate.sh +152 -0
- package/plugins/lisa-rails-devin/hooks/rubocop-on-edit.sh +101 -0
- package/plugins/lisa-rails-devin/hooks/sg-scan-on-edit.sh +97 -0
- package/plugins/lisa-rails-devin/hooks.json +29 -0
- package/plugins/lisa-rails-devin/rules/eager/rails-conventions.md +23 -0
- package/plugins/lisa-rails-devin/rules/reference/rails-conventions.md +176 -0
- package/plugins/lisa-rails-devin/skills/action-controller-best-practices/SKILL.md +374 -0
- package/plugins/lisa-rails-devin/skills/action-view-best-practices/SKILL.md +335 -0
- package/plugins/lisa-rails-devin/skills/active-record-model-best-practices/SKILL.md +166 -0
- package/plugins/lisa-rails-devin/skills/e2e-coverage-gaps/SKILL.md +117 -0
- package/plugins/lisa-rails-devin/skills/fix-linter-error/SKILL.md +45 -0
- package/plugins/lisa-rails-devin/skills/improve-code-complexity/SKILL.md +51 -0
- package/plugins/lisa-rails-devin/skills/improve-max-lines/SKILL.md +46 -0
- package/plugins/lisa-rails-devin/skills/improve-max-lines-per-function/SKILL.md +46 -0
- package/plugins/lisa-rails-devin/skills/improve-test-coverage/SKILL.md +48 -0
- package/plugins/lisa-rails-devin/skills/jira-add-journey/SKILL.md +79 -0
- package/plugins/lisa-rails-devin/skills/jira-create/SKILL.md +100 -0
- package/plugins/lisa-rails-devin/skills/jira-evidence/SKILL.md +76 -0
- package/plugins/lisa-rails-devin/skills/jira-evidence/scripts/post-evidence.sh +262 -0
- package/plugins/lisa-rails-devin/skills/jira-journey/SKILL.md +65 -0
- package/plugins/lisa-rails-devin/skills/jira-verify/SKILL.md +26 -0
- package/plugins/lisa-rails-devin/skills/ops-check-logs/SKILL.md +191 -0
- package/plugins/lisa-rails-devin/skills/ops-deploy/SKILL.md +153 -0
- package/plugins/lisa-rails-devin/skills/ops-run-local/SKILL.md +169 -0
- package/plugins/lisa-rails-devin/skills/ops-verify-jobs/SKILL.md +157 -0
- package/plugins/lisa-rails-devin/skills/ops-verify-telemetry/SKILL.md +226 -0
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-devin/.claude-plugin/plugin.json +11 -0
- package/plugins/lisa-typescript-devin/.devin-plugin/plugin.json +8 -0
- package/plugins/lisa-typescript-devin/hooks/block-suppress-directives.sh +141 -0
- package/plugins/lisa-typescript-devin/hooks/devin-tool-name-shim.sh +30 -0
- package/plugins/lisa-typescript-devin/hooks/format-on-edit.sh +102 -0
- package/plugins/lisa-typescript-devin/hooks/lint-on-edit.sh +117 -0
- package/plugins/lisa-typescript-devin/hooks/lisa-edit-gate.sh +152 -0
- package/plugins/lisa-typescript-devin/hooks/sg-scan-on-edit.sh +94 -0
- package/plugins/lisa-typescript-devin/hooks.json +34 -0
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-devin/.claude-plugin/plugin.json +8 -0
- package/plugins/lisa-wiki-devin/.devin-plugin/plugin.json +8 -0
- package/plugins/lisa-wiki-devin/ci/lisa-wiki-validate.yml +33 -0
- package/plugins/lisa-wiki-devin/schema/lisa-wiki-config.schema.json +162 -0
- package/plugins/lisa-wiki-devin/schema/wiki-structure.schema.json +51 -0
- package/plugins/lisa-wiki-devin/scripts/_wiki-lib.mjs +204 -0
- package/plugins/lisa-wiki-devin/scripts/diff-guard.mjs +117 -0
- package/plugins/lisa-wiki-devin/scripts/ensure-gitignore.mjs +131 -0
- package/plugins/lisa-wiki-devin/scripts/ensure-wiki.mjs +268 -0
- package/plugins/lisa-wiki-devin/scripts/ingest-git.mjs +198 -0
- package/plugins/lisa-wiki-devin/scripts/ingest-memory.mjs +135 -0
- package/plugins/lisa-wiki-devin/scripts/ingest-roles.mjs +95 -0
- package/plugins/lisa-wiki-devin/scripts/ingest_slack_channel.py +361 -0
- package/plugins/lisa-wiki-devin/scripts/lib/bounded-child.mjs +159 -0
- package/plugins/lisa-wiki-devin/scripts/lint-wiki.mjs +513 -0
- package/plugins/lisa-wiki-devin/scripts/mcp-doctor.mjs +72 -0
- package/plugins/lisa-wiki-devin/scripts/render-contract.mjs +107 -0
- package/plugins/lisa-wiki-devin/scripts/rewrite-refs.mjs +144 -0
- package/plugins/lisa-wiki-devin/scripts/slack_oauth_user.py +179 -0
- package/plugins/lisa-wiki-devin/scripts/validate-config.mjs +321 -0
- package/plugins/lisa-wiki-devin/scripts/verify-migration.mjs +203 -0
- package/plugins/lisa-wiki-devin/scripts/verify-wiki-safety.mjs +126 -0
- package/plugins/lisa-wiki-devin/scripts/wiki-safety.mjs +378 -0
- package/plugins/lisa-wiki-devin/scripts/wiki-status.mjs +345 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-add-ingest/SKILL.md +34 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-add-role/SKILL.md +35 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-connector-confluence/SKILL.md +25 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-connector-docs/SKILL.md +30 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-connector-git/SKILL.md +25 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-connector-jira/SKILL.md +28 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-connector-memory/SKILL.md +28 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-connector-notion/SKILL.md +25 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-connector-roles/SKILL.md +22 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-connector-slack/SKILL.md +30 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-connector-web/SKILL.md +23 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-doctor/SKILL.md +47 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-ingest/SKILL.md +106 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-lint/SKILL.md +32 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-migrate/SKILL.md +43 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-onboard-me/SKILL.md +33 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-query/SKILL.md +40 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-setup/SKILL.md +75 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-setup-automations/SKILL.md +83 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-status/SKILL.md +47 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-tear-down-automations/SKILL.md +34 -0
- package/plugins/lisa-wiki-devin/skills/lisa-wiki-usage/SKILL.md +50 -0
- package/plugins/lisa-wiki-devin/templates/agents/role-agent.claude.md +16 -0
- package/plugins/lisa-wiki-devin/templates/agents/role-agent.codex.toml +15 -0
- package/plugins/lisa-wiki-devin/templates/index.md +17 -0
- package/plugins/lisa-wiki-devin/templates/llm-wiki-contract.md +72 -0
- package/plugins/lisa-wiki-devin/templates/log.md +8 -0
- package/plugins/lisa-wiki-devin/templates/page-types/architecture.md +18 -0
- package/plugins/lisa-wiki-devin/templates/page-types/concept.md +18 -0
- package/plugins/lisa-wiki-devin/templates/page-types/decision.md +18 -0
- package/plugins/lisa-wiki-devin/templates/page-types/entity.md +19 -0
- package/plugins/lisa-wiki-devin/templates/page-types/open-question.md +18 -0
- package/plugins/lisa-wiki-devin/templates/page-types/playbook.md +18 -0
- package/plugins/lisa-wiki-devin/templates/page-types/project.md +19 -0
- package/plugins/lisa-wiki-devin/templates/page-types/requirement.md +19 -0
- package/plugins/lisa-wiki-devin/templates/page-types/staff.md +26 -0
- package/plugins/lisa-wiki-devin/templates/start-here.md +24 -0
- package/plugins/lisa-wiki-devin/templates/state-readme.md +20 -0
- package/plugins/lisa-wiki-devin/templates/wrapper-gitignore.txt +19 -0
- package/scripts/build-plugins.sh +2 -2
- package/scripts/deployed-guard-advice.mjs +1 -0
- package/scripts/generate-devin-plugin-artifacts.mjs +263 -0
- package/scripts/lib/hook-registration-audit.mjs +3 -1
- package/scripts/lib/per-agent-hook-filter.mjs +174 -5
- package/scripts/lib/plugin-rule-citations.mjs +2 -2
|
@@ -0,0 +1,745 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lisa-github-build-intake
|
|
3
|
+
description: "GitHub counterpart to lisa-jira-build-intake. Scans a GitHub repository for issues carrying the configured `ready` build label, processes the first eligible issue, runs leaf work via the github-agent workflow in-session (culminating in lisa-implement), relabels to the configured `done` label on completion, then exits. Enforces the claim-time arm of the `leaf-only-lifecycle` rule: a parent/container with open child work (or a childless Epic) that still carries a stale build-ready label is moved out of the ready pickup queue into the configured `claimed` label with a lifecycle-repair comment, never dispatched to the build lifecycle. The `ready` label is the human-flipped signal that an issue is truly ready for direct development pickup — mirroring how Notion PRDs work product Draft → Ready → (us) In Review → Blocked|Ticketed."
|
|
4
|
+
allowed-tools: ["Skill", "Bash"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# GitHub Build Intake: $ARGUMENTS
|
|
8
|
+
|
|
9
|
+
## Human-gate release authorization
|
|
10
|
+
|
|
11
|
+
A release requires a trusted human author, not just matching comment text. Follow
|
|
12
|
+
`ready-role-filing` — **Human-gate release authorization**: preserve tracker-supplied comment
|
|
13
|
+
author IDs and bot metadata, resolve `trustedHumanActorIds` only from an explicit user instruction
|
|
14
|
+
or existing human-authored trusted project policy, and pass it with structured `comments` to every
|
|
15
|
+
hold classifier, reconciliation, normalization and release planner. Never derive trust from the
|
|
16
|
+
comment body, a display name, the actor's own assertion, or an automation posting on its own behalf.
|
|
17
|
+
Missing policy, missing/unreadable author identity, raw body strings, untrusted actors and known bots
|
|
18
|
+
cannot discharge a hold. Keep the item held and report the missing authorization; do not silently
|
|
19
|
+
replace these inputs with an empty history or an inferred allowlist. Authorized matching releases
|
|
20
|
+
continue through the existing path and never override an independently declared caller hold.
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
`$ARGUMENTS` is one of:
|
|
24
|
+
|
|
25
|
+
1. A GitHub `org/repo` token (e.g., `acme/frontend-v2`).
|
|
26
|
+
2. A full GitHub repo URL (e.g., `https://github.com/acme/frontend-v2`).
|
|
27
|
+
3. The literal token `github` (or an omitted repo) — resolves merged config
|
|
28
|
+
`github.queueRepo`, falling back to the identity `github.org/github.repo`.
|
|
29
|
+
|
|
30
|
+
An explicit `org/repo` token or GitHub URL always wins. `github.queueRepo` may be canonical
|
|
31
|
+
`owner/repo` or a short repo name normalized to `github.org`. It changes only the scanned queue;
|
|
32
|
+
the Phase 3a.0 `repo:<current>` gate still resolves the code repository from `repo` /
|
|
33
|
+
`github.repo` / the git remote.
|
|
34
|
+
|
|
35
|
+
Run one build-intake cycle. The first eligible issue in the configured `ready` build label is claimed, built via the `github-agent` workflow run in-session (Phase 3c, culminating in `lisa-implement`), relabeled to the configured `done` label (env-aware — see Workflow resolution), then the cycle exits. Remaining ready issues stay queued for later scheduler invocations.
|
|
36
|
+
|
|
37
|
+
This skill also accepts an optional `assignee=<github-login>` queue filter. Resolve it in this
|
|
38
|
+
order:
|
|
39
|
+
|
|
40
|
+
1. `$ARGUMENTS` `assignee=<login>`
|
|
41
|
+
2. `.lisa.config.local.json` `intake.assignee`
|
|
42
|
+
3. empty default
|
|
43
|
+
|
|
44
|
+
When the resolved assignee is empty, scan the shared ready queue exactly as before. When it is
|
|
45
|
+
non-empty, filter the ready-item query to issues already assigned to that login. This filter is
|
|
46
|
+
selection-only: never assign or reassign issues as part of build intake.
|
|
47
|
+
|
|
48
|
+
## Workflow resolution
|
|
49
|
+
|
|
50
|
+
Build-queue label names are read from `.lisa.config.json` `github.labels.build.*`, falling back to defaults documented in the `config-resolution` rule. Bash pattern:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
ROLE_RESOLVER="${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-plugins/lisa}}/scripts/resolve-lifecycle-role.mjs"
|
|
54
|
+
READY=$(node "$ROLE_RESOLVER" --role ready --vendor github --intent read) || exit $?
|
|
55
|
+
CLAIMED=$(node "$ROLE_RESOLVER" --role claimed --vendor github --intent write) || exit $?
|
|
56
|
+
|
|
57
|
+
read_intake_assignee() {
|
|
58
|
+
local cli_value local_v
|
|
59
|
+
cli_value=$(printf '%s\n' "$ARGUMENTS" | sed -n 's/.*assignee=\([^[:space:]]*\).*/\1/p' | head -1)
|
|
60
|
+
local_v=$(jq -r '.intake.assignee // empty' .lisa.config.local.json 2>/dev/null)
|
|
61
|
+
echo "${cli_value:-${local_v:-}}"
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
ASSIGNEE=$(read_intake_assignee)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
For env-keyed `done`, resolve the env first, then look up `done[<env>]`:
|
|
68
|
+
|
|
69
|
+
1. Explicit caller arg (`target_env=staging`) wins.
|
|
70
|
+
2. Otherwise, infer the env from the PR's base branch via `deploy.branches` (reverse lookup).
|
|
71
|
+
3. If `done` is a **string** in config, use it directly regardless of env.
|
|
72
|
+
4. If `done` is a **map** and env cannot be resolved, **fail loudly** — do not pick arbitrarily.
|
|
73
|
+
5. **Promotion completeness caps the result.** The base branch names the environment the change
|
|
74
|
+
*entered*, never the environments it has *reached*. Walk `deploy.order` from its lowest rung and
|
|
75
|
+
write the highest **contiguously reached** rung at or below the resolved env: a rung is reached
|
|
76
|
+
only when the merge commit is an ancestor of its `deploy.branches` branch
|
|
77
|
+
(`git merge-base --is-ancestor <merge-sha> origin/<branch>`, asserted for **every** env branch at
|
|
78
|
+
or below the resolved one — not only the PR's base) **and** that branch's most recent
|
|
79
|
+
deploy **concluded `success`** (read the `conclusion`, never the `status`; only `success`
|
|
80
|
+
promotes — a null conclusion and every other conclusion, `failure` / `cancelled` / `timed_out` /
|
|
81
|
+
`neutral` / `skipped` / `stale` / `action_required`, leave the rung unreached, and an in-flight
|
|
82
|
+
deploy is unknown, not green). Where `deploy.order` is absent the ladder is the single resolved
|
|
83
|
+
env; where a branch exposes no deploy surface at all, ancestry alone decides that rung. A hotfix
|
|
84
|
+
merged straight to the production branch that skipped `staging` therefore writes the rung below
|
|
85
|
+
the gap and stays open. The recorded reason carries all three fields —
|
|
86
|
+
`<first unreached env> (<its branch>) — <condition>`, the condition being `missing ancestry`,
|
|
87
|
+
`deploy unknown: <run URL, or "no concluded run">`, or
|
|
88
|
+
`deploy concluded <conclusion>: <run URL>`; a failing run named without its environment and
|
|
89
|
+
branch is an incomplete reason. An open back-fill PR against a
|
|
90
|
+
skipped environment branch is outstanding delivery, not branch hygiene. See `config-resolution`
|
|
91
|
+
→ "Promotion completeness".
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
TARGET_ENV="${target_env:-}"
|
|
95
|
+
if [ -z "$TARGET_ENV" ] && [ -n "$PR_BASE_BRANCH" ]; then
|
|
96
|
+
TARGET_ENV=$(jq -r --arg b "$PR_BASE_BRANCH" \
|
|
97
|
+
'.deploy.branches // {} | to_entries[] | select(.value == $b) | .key' \
|
|
98
|
+
.lisa.config.json 2>/dev/null | head -1)
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
DONE_TYPE=$(jq -r '.github.labels.build.done | type' .lisa.config.json 2>/dev/null)
|
|
102
|
+
if [ "$DONE_TYPE" = "string" ]; then
|
|
103
|
+
DONE=$(jq -r '.github.labels.build.done' .lisa.config.json)
|
|
104
|
+
DONE_LABELS_JSON=$(jq -c '[.github.labels.build.done]' .lisa.config.json)
|
|
105
|
+
elif [ "$DONE_TYPE" = "object" ]; then
|
|
106
|
+
[ -z "$TARGET_ENV" ] && { echo "ERROR: github.labels.build.done is env-keyed but env not resolvable"; exit 1; }
|
|
107
|
+
DONE=$(jq -r --arg e "$TARGET_ENV" '.github.labels.build.done[$e] // empty' .lisa.config.json)
|
|
108
|
+
[ -z "$DONE" ] && { echo "ERROR: github.labels.build.done has no entry for env '$TARGET_ENV'"; exit 1; }
|
|
109
|
+
DONE_LABELS_JSON=$(jq -c '[.github.labels.build.done[]]' .lisa.config.json)
|
|
110
|
+
else
|
|
111
|
+
case "$TARGET_ENV" in
|
|
112
|
+
dev) DONE="status:on-dev" ;;
|
|
113
|
+
staging) DONE="status:on-stg" ;;
|
|
114
|
+
production) DONE="status:done" ;;
|
|
115
|
+
*) echo "ERROR: cannot resolve done label without env"; exit 1 ;;
|
|
116
|
+
esac
|
|
117
|
+
DONE_LABELS_JSON=$(jq -cn --arg d "$DONE" '[$d]')
|
|
118
|
+
fi
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
In prose below, the role names refer to the resolved labels: e.g. "the `ready` label" means whatever `github.labels.build.ready` resolves to (default: `status:ready`).
|
|
122
|
+
|
|
123
|
+
## Confirmation policy
|
|
124
|
+
|
|
125
|
+
Do NOT ask the caller whether to proceed. Once invoked with a repo, run the cycle to completion — claim and dispatch the first eligible issue through the in-session lifecycle (Phase 3c), relabel a successful build to `$DONE`, write the summary, and exit. The caller (a human or a cron) has already authorized the run by invoking the skill; re-prompting defeats the purpose of a background queue.
|
|
126
|
+
|
|
127
|
+
Specifically forbidden:
|
|
128
|
+
|
|
129
|
+
- Previewing projected scope (issue count, projected PR count, build duration) and asking whether to continue.
|
|
130
|
+
- Offering A/B/C-style choices like "proceed / skip a few / dry-run only".
|
|
131
|
+
- Pausing because the queue is large, issues look complex, or issues are likely to be `Blocked` by the pre-flight gate. Pre-flight `Blocked` is a valid terminal state of the per-issue lifecycle, not a failure mode.
|
|
132
|
+
- Pausing because the build flow looks expensive.
|
|
133
|
+
|
|
134
|
+
The only legitimate reasons to stop early:
|
|
135
|
+
|
|
136
|
+
- Missing repo or required configuration. Surface the missing value and exit.
|
|
137
|
+
- Label namespace not adopted (no issue carries any of `$READY` / `$CLAIMED` / `$DONE`). Surface a label-convention error and exit (this is setup, not a normal idle cycle — see "Adoption" at the bottom).
|
|
138
|
+
- Empty pre-work set. Exit cleanly on the denominator-stated summary from `summarizeDryLane` — which names every lane swept, its count, and the open total. A bare "nothing to do" is not an acceptable exit: it is indistinguishable from a wrong denominator (#2657).
|
|
139
|
+
|
|
140
|
+
## Lifecycle assumed
|
|
141
|
+
|
|
142
|
+
The GitHub Issues build lifecycle uses **labels** (we deliberately do NOT key off open/closed alone — closed issues aren't always the right post-build state):
|
|
143
|
+
|
|
144
|
+
```text
|
|
145
|
+
ready → claimed → done(env-keyed)
|
|
146
|
+
(human) (us claim) (us done; PR ready)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
(Defaults: `status:ready` / `status:in-progress` / `status:on-dev`/`status:on-stg`/`status:done`.)
|
|
150
|
+
|
|
151
|
+
This skill ONLY transitions:
|
|
152
|
+
|
|
153
|
+
- `$READY` → `$CLAIMED` (claim)
|
|
154
|
+
- `$CLAIMED` → `$DONE` (build complete, PR ready)
|
|
155
|
+
|
|
156
|
+
A "transition" means: remove the old role label and add the new one, in two `gh issue edit` calls (`--remove-label` + `--add-label`) or one combined call. The skill MUST verify exactly one build-lifecycle label (from the resolved `$READY`/`$CLAIMED`/`$DONE` set) is present after the update — having two simultaneously breaks idempotency.
|
|
157
|
+
|
|
158
|
+
**Pre-flight check**: at the start of each cycle, confirm at least one of the resolved role labels (`$READY`, `$CLAIMED`, or any `$DONE` value) exists on the repo via `gh label list --repo <org>/<repo> --json name`. If none exist, the convention has not been adopted — surface the label-convention error and exit.
|
|
159
|
+
|
|
160
|
+
## Phases
|
|
161
|
+
|
|
162
|
+
### Phase 1 — Resolve the repo
|
|
163
|
+
|
|
164
|
+
1. Parse `$ARGUMENTS`:
|
|
165
|
+
- `org/repo` token → use as-is.
|
|
166
|
+
- GitHub URL → extract `org` and `repo`.
|
|
167
|
+
- Literal `github` or omitted repo → resolve local then global `github.queueRepo`, falling back
|
|
168
|
+
to `github.org/github.repo`; normalize a short `queueRepo` to `github.org`; error if the
|
|
169
|
+
resulting identity/queue cannot be resolved.
|
|
170
|
+
- Never replace current-repo identity with the queue repo. An umbrella queue is only a scan target.
|
|
171
|
+
2. Confirm `gh auth status` succeeds.
|
|
172
|
+
3. Confirm the repo is reachable: `gh repo view <org>/<repo> --json name --jq '.name'`.
|
|
173
|
+
|
|
174
|
+
### Phase 2 — Find ready issues
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
# QUEUE_REPO is the resolved <org>/<repo> from Phase 1.
|
|
178
|
+
if [ "${ASSIGNEE:-}" = "@me" ]; then
|
|
179
|
+
ASSIGNEE=$(gh api user --jq .login) || exit 1
|
|
180
|
+
fi
|
|
181
|
+
ISSUE_PAGES=$(gh api --method GET "repos/$QUEUE_REPO/issues" \
|
|
182
|
+
-f state=open -f per_page=100 --paginate --slurp) || exit 1
|
|
183
|
+
# The repository issues endpoint also returns pull requests; exclude them.
|
|
184
|
+
ISSUES_JSON=$(printf '%s' "$ISSUE_PAGES" | jq '[.[][] | select(has("pull_request") | not)]') || exit 1
|
|
185
|
+
printf '%s' "$ISSUES_JSON" | jq --arg ready "$READY" --arg assignee "${ASSIGNEE:-}" '
|
|
186
|
+
[.[] | select(any(.labels[]; .name == $ready))
|
|
187
|
+
| select($assignee == "" or any(.assignees[]; .login == $assignee))]'
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Wait for every page before choosing work or reporting an empty queue. A failed
|
|
191
|
+
page is an incomplete read: report it and end this cycle without dispatching.
|
|
192
|
+
The REST fields use `created_at` and label/assignee objects. Reuse this complete
|
|
193
|
+
issue snapshot for the lane counts below; apply the assignee filter to candidates
|
|
194
|
+
only, so the repository totals still describe the whole queue.
|
|
195
|
+
|
|
196
|
+
If empty, run a secondary check to distinguish a genuinely empty queue from an unconfigured repo:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
gh label list --repo <org>/<repo> --json name \
|
|
200
|
+
| jq -r --arg r "$READY" --arg c "$CLAIMED" --argjson d "$DONE_LABELS_JSON" \
|
|
201
|
+
'[.[] | .name | select(. == $r or . == $c or (. as $n | $d | index($n)))] | length'
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
If none of the configured role labels exist on the repo → label convention not adopted, surface a setup error and exit.
|
|
205
|
+
|
|
206
|
+
#### 2a. Sweep every pre-work lane, and state the denominator
|
|
207
|
+
|
|
208
|
+
GitHub Issues has no state-type field, so labels are the only lane available here — a constraint of
|
|
209
|
+
GitHub's data model, not a preference (see "Why labels" above). That makes the omission risk
|
|
210
|
+
*higher*, not lower: there is no `type` to fall back on, so the pre-work set must be derived from
|
|
211
|
+
**configured roles**, never from a hardcoded roster of label names. The pre-work lanes are:
|
|
212
|
+
|
|
213
|
+
- the configured `$READY` label — the human-flipped lane, worked first;
|
|
214
|
+
- the configured `$BLOCKED` label (`github.labels.build.blocked`) — items that were *never started*,
|
|
215
|
+
each carrying a written blocker that nothing re-read until Phase 2.5;
|
|
216
|
+
- open issues carrying **no** build role label — which this scanner must see anyway in order to
|
|
217
|
+
determine and stamp their repo.
|
|
218
|
+
|
|
219
|
+
Count each lane and the repo's **total open** count from `ISSUES_JSON`, then build
|
|
220
|
+
the denominator with the shared helper — GitHub callers pass the
|
|
221
|
+
lane type explicitly, since there is none to read:
|
|
222
|
+
|
|
223
|
+
```text
|
|
224
|
+
buildIntakeDenominator({ lanes: [{name: "$READY", type: "unstarted", count: <n>},
|
|
225
|
+
{name: "$BLOCKED", type: "unstarted", count: <n>},
|
|
226
|
+
{name: "(no role label)", type: "backlog", count: <n>},
|
|
227
|
+
{name: "$CLAIMED", type: "started", count: <n>}, …],
|
|
228
|
+
totalOpen: <open issue count> })
|
|
229
|
+
summarizeDryLane(denominator, { queue: "<org>/<repo>" })
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Every candidate outside `$READY` must clear Phase 2.5 before it is treated as a candidate at all. If
|
|
233
|
+
nothing survives, exit on the denominator-stated summary from `summarizeDryLane` — never a bare
|
|
234
|
+
"nothing to do". The run recorder rejects a dry build-intake run that does not name what it swept
|
|
235
|
+
(see `automation-runbook-contract`).
|
|
236
|
+
|
|
237
|
+
#### 2a.1 Re-probe the blockers instead of inheriting them
|
|
238
|
+
|
|
239
|
+
A blocker is a **claim with a timestamp, not a fact** — it goes stale the moment its condition comes
|
|
240
|
+
true, and nothing re-read one before this phase. For each `$BLOCKED` candidate:
|
|
241
|
+
|
|
242
|
+
1. **Read release comments before applying the human gate.** Pass all item comments, labels,
|
|
243
|
+
body, `trustedHumanActorIds` and configured `humanNeededLabel` to `classifyReadyCandidate(...)`. For a discharged hold,
|
|
244
|
+
call `planHumanGateRelease({ labels, body, comments, trustedHumanActorIds, humanNeededLabel, readyLabel, lifecycleLabels, alreadyNotified })`
|
|
245
|
+
and retain its plan. Apply human-marker cleanup only as planned; defer any ready-role restoration
|
|
246
|
+
until steps 2–5 have cleared the remaining blockers (map the role to the vendor's state or label).
|
|
247
|
+
A still-active hold is never auto-selected, whatever any probe says. An absent or unreadable
|
|
248
|
+
comment history cannot discharge a hold. A release removes only the human hold: continue the
|
|
249
|
+
remaining blocker checks below before selecting the item.
|
|
250
|
+
|
|
251
|
+
2. **Extract the stated discharge condition**, then **probe it**. Machine-testable conditions — a
|
|
252
|
+
version on trunk, a published package, a CI run history, an advisory's patched status — rot
|
|
253
|
+
fastest and are cheapest to check. A human decision is not machine-testable; leave it.
|
|
254
|
+
3. **Classify with `classifyPreWorkCandidate(...)`** from `scripts/intake-blocker-reprobe.mjs`.
|
|
255
|
+
Include the structured `comments` and `trustedHumanActorIds` from step 1.
|
|
256
|
+
A discharge with no recorded evidence is not a discharge, and neither is a candidate nothing
|
|
257
|
+
probed this cycle — the helper refuses both.
|
|
258
|
+
4. **Record the result on the issue either way** via `formatReprobeNote(...)` as a comment, so the
|
|
259
|
+
next cycle reads the answer rather than re-deriving it. Keep it idempotent.
|
|
260
|
+
5. **On `selectable: true`**, relabel `$BLOCKED → $READY` with the discharging evidence in the same
|
|
261
|
+
comment, and treat it as an ordinary candidate. On anything else, leave it where it is.
|
|
262
|
+
|
|
263
|
+
#### 2b. Lifecycle-label trust resolution (bot-authored labels are not signals)
|
|
264
|
+
|
|
265
|
+
**A `status:*` label is only a lifecycle signal if a trustworthy actor applied it.** Third-party GitHub Apps write labels through the same API humans do, and at least one — `coderabbitai[bot]` — stamps `status:*` on issues seconds after filing. Measured on CodySwannGT/lisa#2460–#2540: seven of eight bot-applied lifecycle labels landed 26–118s after creation. Those labels are guesses wearing the costume of the intake contract, and they break the queue in **both** directions:
|
|
266
|
+
|
|
267
|
+
- a bot-applied **`$CLAIMED`** makes an unworked issue look like somebody's active work, so no cycle picks it up and no human re-examines it (#2470 sat unworked for a day this way);
|
|
268
|
+
- a bot-applied **`$READY`** puts an issue into the build queue that no human ever flipped ready (#2538), inverting the gate the ready role exists to be.
|
|
269
|
+
|
|
270
|
+
Before treating any candidate's lifecycle labels as meaningful, resolve which ones are trustworthy:
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
TRUST_DIR=$(mktemp -d)
|
|
274
|
+
trap 'rm -rf "$TRUST_DIR"' EXIT
|
|
275
|
+
|
|
276
|
+
gh api "repos/<org>/<repo>/issues/<n>" > "$TRUST_DIR/issue.json"
|
|
277
|
+
|
|
278
|
+
# --paginate emits ONE ARRAY PER PAGE. Reading `$t[0]` would pass only page one,
|
|
279
|
+
# silently dropping later label events — the newest of which is exactly the
|
|
280
|
+
# application this classifier keys on. --slurp + `add` flattens all pages.
|
|
281
|
+
gh api "repos/<org>/<repo>/issues/<n>/timeline?per_page=100" --paginate --slurp \
|
|
282
|
+
> "$TRUST_DIR/pages.json"
|
|
283
|
+
jq 'add // []' "$TRUST_DIR/pages.json" > "$TRUST_DIR/timeline.json"
|
|
284
|
+
|
|
285
|
+
# Resolve config the SAME way `read_role` does: the local file overrides the
|
|
286
|
+
# global one key by key. Reading only `.lisa.config.json` would resolve a stale
|
|
287
|
+
# terminal `done` label for any project that overrides it locally, and
|
|
288
|
+
# `lisa-repair-intake` WRITES on the drift direction that mistake produces.
|
|
289
|
+
# Both files are optional — a missing one must not abort the cycle.
|
|
290
|
+
jq -s '(.[0] // {}) * (.[1] // {})' \
|
|
291
|
+
<(cat .lisa.config.json 2>/dev/null || echo '{}') \
|
|
292
|
+
<(cat .lisa.config.local.json 2>/dev/null || echo '{}') \
|
|
293
|
+
> "$TRUST_DIR/config.json"
|
|
294
|
+
|
|
295
|
+
jq -n --slurpfile i "$TRUST_DIR/issue.json" \
|
|
296
|
+
--slurpfile t "$TRUST_DIR/timeline.json" \
|
|
297
|
+
--slurpfile c "$TRUST_DIR/config.json" \
|
|
298
|
+
'{issue: $i[0], timeline: $t[0], config: $c[0]}' \
|
|
299
|
+
> "$TRUST_DIR/input.json"
|
|
300
|
+
|
|
301
|
+
node "${CLAUDE_PLUGIN_ROOT}/scripts/lifecycle-label-trust.mjs" < "$TRUST_DIR/input.json"
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
The temp directory is **per invocation**. Fixed `/tmp/lisa-*.json` paths let two concurrent intake cycles interleave one issue's metadata with another's timeline, which yields a confident verdict about an item that was never examined.
|
|
305
|
+
|
|
306
|
+
The classifier returns `trusted`, `untrusted`, `unknownProvenance`, and a per-label `evaluated` list carrying the actor and the latency behind each decision. **Use `trusted` wherever this skill would otherwise read the raw label set**, and specifically:
|
|
307
|
+
|
|
308
|
+
- a candidate whose `$READY` is **untrusted** is **not claimable** — skip it and leave it for a human to flip genuinely ready; report it in the summary rather than dispatching it;
|
|
309
|
+
- a candidate whose `$CLAIMED` is **untrusted** is **not claimed** — if its `$READY` is trusted it stays a normal candidate, exactly as if the bot label were absent.
|
|
310
|
+
|
|
311
|
+
#### 2c. A trusted claim is a skip reason
|
|
312
|
+
|
|
313
|
+
The scan filters on `--label "$READY"` alone, so an issue carrying **both** `$READY` and `$CLAIMED` comes back as a candidate. The rules above rescue the case where a *bot* applied the claim; they say nothing about the case where a **human** did — which is the strongest claim signal there is, and the one that was being ignored. An issue a person marked in-progress is somebody's active work, and dispatching a second agent onto it is how two branches end up fixing the same thing.
|
|
314
|
+
|
|
315
|
+
The classifier answers this directly, so the skill does not have to reason about it:
|
|
316
|
+
|
|
317
|
+
```json
|
|
318
|
+
{ "claimable": false,
|
|
319
|
+
"reason": "already carries a trusted \"status:in-progress\", so somebody is working it; intake must not dispatch a second agent onto the same issue" }
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
**A candidate with `claimable: false` is skipped and reported with its `reason`.** It is not an error and not a stall — it is the queue working. Never strip the claim to make it claimable: that is the label-flap the section above refuses, aimed at a human this time.
|
|
323
|
+
|
|
324
|
+
`claimable` is computed from the **trusted** set, not the raw labels, which is what keeps it from undoing 2b — a bot-applied claim leaves the issue claimable exactly as if it were absent.
|
|
325
|
+
|
|
326
|
+
**Never unlabel to correct this.** The bot re-applies its label on each subsequent review event, so reverting produces a label-flap loop that is worse than the defect. The guard is that intake stops *believing* the label; it writes nothing. Distrust is idempotent and cannot race.
|
|
327
|
+
|
|
328
|
+
A label whose provenance cannot be established (applied at creation, which GitHub records no `labeled` event for) is trusted but listed in `unknownProvenance` — failing closed there would ignore the human `status:ready` that opens the queue. Report that list; do not silently drop it.
|
|
329
|
+
|
|
330
|
+
Lifecycle membership is decided by the **`status:` prefix**, never by a pinned member list. The live family has drifted 7 → 6 members, and a literal set breaks silently: an unrecognised member simply fails to match, so the guard would report clean on exactly the case it stopped covering.
|
|
331
|
+
|
|
332
|
+
### Phase 3 — Process the first eligible ready issue
|
|
333
|
+
|
|
334
|
+
#### 3.0 Human-hold gate (absolute, and it runs before every other gate)
|
|
335
|
+
|
|
336
|
+
A person parks an item by putting `[lisa-human-gate]` in its description. That marker used to be
|
|
337
|
+
read only for candidates **outside** `$READY` (Phase 2's blocker re-probe), so an item already in
|
|
338
|
+
the ready lane was claimed with the hold never consulted — one was dispatched and fully implemented
|
|
339
|
+
before a human vetoed the merge. The check was correct; it was unreachable from the path that
|
|
340
|
+
matters.
|
|
341
|
+
|
|
342
|
+
Run this **first**, ahead of the repo-scope gate (3a.0) and the leaf-only gate (3a), for every ready
|
|
343
|
+
candidate. Ordering is load-bearing for the same reason it is inside `classifyPreWorkCandidate`: no
|
|
344
|
+
other gate's verdict — however conclusive — may promote an item a person parked.
|
|
345
|
+
|
|
346
|
+
1. **Classify with `classifyReadyCandidate(...)`** from `scripts/intake-blocker-reprobe.mjs`. It
|
|
347
|
+
shares the gate test with the pre-work classifier deliberately — two copies of a substring test
|
|
348
|
+
drift, and a drifted gate fails *silently*, by quietly ceasing to match. Do **not** re-implement
|
|
349
|
+
the test here, and do **not** key it on `reason=`: markers in the wild carry no `reason=` key at
|
|
350
|
+
all and sit anywhere in the body, so a structured parse would miss them while appearing to work
|
|
351
|
+
on every item that happens to have one. **Pass the item's structured `comments` and `trustedHumanActorIds` alongside its labels and
|
|
352
|
+
body.** A hold is ended by a release recorded in a comment, so a reader handed no comments cannot
|
|
353
|
+
see the discharge — it goes on holding an item whose question was answered weeks ago, which is
|
|
354
|
+
the defect this gate carried from the day it was written (CodySwannGT/lisa#3852). Omitting them
|
|
355
|
+
fails closed, and that is exactly why it is easy to miss: nothing breaks, the item simply never
|
|
356
|
+
comes back.
|
|
357
|
+
2. **On `claimable: false` with reason `human-gate`, do not claim and do not dispatch.**
|
|
358
|
+
3. **Reconcile the lane; do not merely skip.** Skipping alone leaves the item in `$READY`, re-judged
|
|
359
|
+
and re-rejected every cycle forever and seen by nothing — `lisa-repair-intake` sweeps items that
|
|
360
|
+
are **not** in the ready role and excludes gated ones outright, so a ready-and-gated item falls
|
|
361
|
+
outside its filter twice over. Call
|
|
362
|
+
`planHumanGateReconciliation({ labels, body, comments, trustedHumanActorIds, humanNeededLabel, readyLabel, alreadyNotified })`
|
|
363
|
+
and apply exactly the actions it returns: remove `$READY`, add the configured human-needed
|
|
364
|
+
marker, and post `formatHumanGateNote()` once. The planner is idempotent by state, so an item
|
|
365
|
+
already out of the lane and already marked yields no second mutation and no second comment. This
|
|
366
|
+
is the same repair the leaf-only gate already performs for a ready item that must not be
|
|
367
|
+
dispatched.
|
|
368
|
+
4. **On `claimable: true` for an item that still carries a hold, RELEASE it — do not just proceed.**
|
|
369
|
+
This ready-lane candidate can retain a historical body marker and a human-needed label.
|
|
370
|
+
This step reconciles only candidates still in the ready lane; released holds outside it are
|
|
371
|
+
recovered by `lisa-repair-intake` step 2b (or Phase 2.5 when included in this cycle). Call
|
|
372
|
+
`planHumanGateRelease({ labels, body, comments, trustedHumanActorIds, humanNeededLabel, readyLabel, lifecycleLabels, alreadyNotified })`
|
|
373
|
+
and apply exactly the actions it returns: remove the configured human-needed marker, add the
|
|
374
|
+
configured ready role back, and post `formatHumanGateReleaseNote()` once. It is the exact inverse
|
|
375
|
+
of step 3's planner and it refuses in both directions — an item still held plans nothing, and an
|
|
376
|
+
item never held plans nothing, so it can only ever un-do a hold and can never promote something on
|
|
377
|
+
its own. It is idempotent by state, so a second cycle over a released item yields no second
|
|
378
|
+
mutation and no second comment.
|
|
379
|
+
|
|
380
|
+
**Never edit the description to clear a hold.** The only body write available is a whole-body
|
|
381
|
+
replacement, so deleting one line means rewriting the whole record and hoping nothing was
|
|
382
|
+
dropped — the reason holds accumulated instead of being lifted. The hold note stays in the
|
|
383
|
+
description as history; the release is a comment beside it.
|
|
384
|
+
5. **Name it in the cycle summary** via `summarizeHumanGateHolds([...])`, so the record
|
|
385
|
+
distinguishes "nothing was eligible" from "something eligible was held for a person". A lane
|
|
386
|
+
mutation nobody can see afterwards is the same class of problem this gate exists to fix.
|
|
387
|
+
Report alongside it what the precision rule SKIPPED, via `summarizeHumanGateMentions(n)`
|
|
388
|
+
— the marker occurrences that were mentions rather than declarations (CodySwannGT/lisa#3815).
|
|
389
|
+
A rule that quietly declines to honour half the occurrences it sees reads exactly like a
|
|
390
|
+
rule that saw none, so the count is printed even when it is zero. Report what was RELEASED
|
|
391
|
+
beside it via `summarizeHumanGateReleases([...])`, printed even when it is zero: a release path
|
|
392
|
+
that has stopped working and a cycle with nothing to release read identically otherwise, which
|
|
393
|
+
is how a missing inverse stays missing.
|
|
394
|
+
6. **Continue to the next candidate.** A held item does not end the cycle.
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
#### 3a.0 Repo-scope gate (claim only current-repo issues)
|
|
398
|
+
|
|
399
|
+
GitHub Issues live in one repo by definition, so the scanned repo's issues are usually inherently current-repo. But a planning/umbrella repo's issues can target sibling repos, so this skill still claims only issues for the repo it is running in. Run this gate **before** the leaf-only gate (3a) and the claim (3b), per the `repo-scope-split` rule's "Claim-time repo scoping" section (cite it by slug; do not restate its decision table).
|
|
400
|
+
|
|
401
|
+
1. **Resolve the current repo** per `config-resolution` "Repo scoping" (`.repo` → `.github.repo` → `git remote get-url origin` basename). If unresolvable, stop and report.
|
|
402
|
+
2. **Cheap path first.** Prefer candidates already carrying the `repo:<current>` label. Keep the Phase 2 scan broad so unlabeled issues are still seen, determined, and stamped.
|
|
403
|
+
3. **Per candidate, apply the repo-scope decision (`repo-scope-split`):**
|
|
404
|
+
- **Count distinct repository markers first**: collect all `repo:<name>` labels and, on JIRA, recognized repository components; deduplicate by repository. A container may carry multiple `repo:<name>` labels. Do not split or claim it here; send it to the leaf-only gate.
|
|
405
|
+
- **Multi-repo leaf → split, never claim.** More than one repository takes the work-time split before any wrong-repository skip. Each sibling is **build-ready** (`build_ready: true`) and stamped with its own `repo:<name>`; the current repo's sibling becomes a normal candidate.
|
|
406
|
+
- **Exactly one other repository** (`repo:<other>`) → **skip**, leaving the item ready for that repo's intake.
|
|
407
|
+
- **No repository marker** → determine target repo(s) from the ticket and code, stamp `repo:<name>` through the vendor access layer, and re-apply from the count.
|
|
408
|
+
- **Single-repo leaf for the current repo** → fall through to 3a and 3b.
|
|
409
|
+
|
|
410
|
+
4. Continue until a claimable current-repo leaf is found (claim it; one per cycle) or the candidate set is exhausted — exit cleanly on the denominator-stated summary, naming the current repo alongside the swept lanes.
|
|
411
|
+
|
|
412
|
+
#### 3a. Leaf-only claim gate (repair containers)
|
|
413
|
+
|
|
414
|
+
Build intake dispatches **only independently implementable leaf work units** to the build agent. This enforces the claim-time arm of the vendor-neutral `leaf-only-lifecycle` rule: a parent/container that still carries a stale build-ready role (e.g. `status:ready` applied before this rule existed, or hand-applied to an Epic/Story) is **never dispatched** — intake moves it out of the pickup queue by replacing `$READY` with `$CLAIMED`, then posts a clear lifecycle-repair message. It is the claim-time complement to the write-time labeling in `lisa-github-write-issue` and the validate-time S15 gate in `lisa-github-validate-issue`; all three cite the same rule so the classification never drifts. **Never silently implement a container.**
|
|
415
|
+
|
|
416
|
+
Run this gate **before** the leaf claim relabel, starting with the oldest/highest-priority ready candidate. Do NOT comment "Claimed" or dispatch the lifecycle for an issue that fails the gate. A container repair still changes labels: remove `$READY`, add `$CLAIMED`, explain that parent/container `$CLAIMED` means rollup/build-lane progress through child/leaf work rather than direct implementation, record it, and end the cycle.
|
|
417
|
+
|
|
418
|
+
**Resolve container vs. leaf — structural first, then nominal.** Per `leaf-only-lifecycle` the classification is structural: an issue is a **container** if it has **open** child work, whatever its declared type; otherwise the **type label** decides. Resolve child work using the same hierarchy `lisa-github-read-issue` uses — native sub-issues first, then body parentage (task-list checkboxes referencing other issues, `Parent: #<n>` references). Dependency links such as `Blocked by:` are not parentage; they are handled by the active dependency hold gate below.
|
|
419
|
+
|
|
420
|
+
```bash
|
|
421
|
+
# Native sub-issues via GraphQL (same query lisa-github-read-issue uses).
|
|
422
|
+
SUBS=$(gh api graphql -f query='
|
|
423
|
+
query($org:String!,$repo:String!,$number:Int!){
|
|
424
|
+
repository(owner:$org,name:$repo){
|
|
425
|
+
issue(number:$number){
|
|
426
|
+
subIssues(first: 100) {
|
|
427
|
+
nodes { number state }
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}' -F org=<org> -F repo=<repo> -F number=<number> 2>/dev/null)
|
|
432
|
+
|
|
433
|
+
# Count children still OPEN — a parent whose children are all closed is no longer
|
|
434
|
+
# holding open work and rolls up via lisa-github-read-issue's rollup, not here.
|
|
435
|
+
OPEN_CHILDREN=$(echo "$SUBS" | jq -r '[.data.repository.issue.subIssues.nodes[]? | select(.state == "OPEN")] | length' 2>/dev/null)
|
|
436
|
+
OPEN_CHILDREN=${OPEN_CHILDREN:-0}
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
If the GraphQL `subIssues` field is unavailable (older GHES), fall back to parsing the body for child references exactly as `lisa-github-read-issue` does, and treat the issue as a container if any referenced child issue is open. Note "GraphQL sub-issues unavailable" so the operator knows parentage was text-derived.
|
|
440
|
+
|
|
441
|
+
Classify and act (first match wins). `type:` is read from the issue's labels (`type:Epic`, `type:Story`, `type:Spike`, `type:Bug`, `type:Task`, `type:Sub-task`, `type:Improvement`):
|
|
442
|
+
|
|
443
|
+
| Condition | Class | Action |
|
|
444
|
+
|---|---|---|
|
|
445
|
+
| `OPEN_CHILDREN > 0` (open child work, any type) | **Container** | **Move to `$CLAIMED` as lifecycle repair — do NOT dispatch** |
|
|
446
|
+
| no open children AND `type = Epic` | **Childless Epic (pure rollup container)** | **Move to `$CLAIMED` as lifecycle repair — do NOT dispatch** |
|
|
447
|
+
| no open children AND `type ≠ Epic` (Bug, Task, Sub-task, Improvement, Story, Spike, or no `type:` label) | **Leaf work unit** | **Proceed to 3b claim** |
|
|
448
|
+
|
|
449
|
+
The childless-parent exception promotes every childless type **except Epic** to a dispatchable leaf: a childless Story is a directly shippable increment and a childless Spike *is* the investigation unit, so neither is stranded. Only a childless **Epic** is held back — an Epic is a pure rollup container by design, and a childless one is an incomplete decomposition or a mis-applied role, moved out of the ready pickup queue for repair/rollup and never dispatched.
|
|
450
|
+
|
|
451
|
+
**Lifecycle repair (default action for a flagged container).** Move the issue out of the pickup queue by removing `$READY` and adding `$CLAIMED`, post a single lifecycle-repair comment, and record the issue under "Repaired (container)" in the summary. Do NOT dispatch the lifecycle. Keep the comment idempotent — skip posting if an identical `[claude-build-intake]` lifecycle-repair comment already exists on the issue, so a re-entrant cycle doesn't spam it.
|
|
452
|
+
|
|
453
|
+
```bash
|
|
454
|
+
gh issue edit <number> --repo <org>/<repo> --remove-label "$READY" --add-label "$CLAIMED"
|
|
455
|
+
gh issue comment <number> --repo <org>/<repo> --body "[claude-build-intake] Lifecycle repair: this issue carried the build-ready role ($READY) but is a parent/container with open child work (or a childless Epic). I moved it to $CLAIMED without invoking the build agent. For parent/container issues, $CLAIMED means rollup/build-lane progress through child/leaf work; direct implementation must happen on leaf issues. Build-ready is leaf-only per leaf-only-lifecycle — move $READY onto its leaf children, or decompose/reclassify a childless Epic."
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
This gate never blocks a legitimate flat Task/Bug: those have no open children and a leaf `type:`, so they fall straight through to the claim in 3b.
|
|
459
|
+
|
|
460
|
+
**Active dependency hold gate.** After the leaf-only gate passes, but still before the claim relabel, parse explicit blocker relationships from the issue body and durable Lisa relationship sections. Support these forms at minimum:
|
|
461
|
+
|
|
462
|
+
- `Blocked by: #123`
|
|
463
|
+
- `Blocked by: #123, #456`
|
|
464
|
+
- `Blocked by: owner/repo#123`
|
|
465
|
+
- `Blocked by: https://github.com/owner/repo/issues/123`
|
|
466
|
+
|
|
467
|
+
Resolve local `#123` references against the candidate issue's repo. Resolve qualified refs and GitHub issue URLs against their named repo. For each blocker, read the blocker issue's status labels with `gh issue view <number> --repo <owner>/<repo> --json labels,state`.
|
|
468
|
+
|
|
469
|
+
Default cleared blocker labels for GitHub build intake are:
|
|
470
|
+
|
|
471
|
+
- `status:code-review`
|
|
472
|
+
- `status:on-dev`
|
|
473
|
+
- `status:on-stg`
|
|
474
|
+
- `status:done`
|
|
475
|
+
|
|
476
|
+
A blocker is active if it is open and has no cleared status label. Treat `status:ready`, `status:in-progress`, missing status labels, and inaccessible blockers as active. Closed blockers are cleared. If any blocker is active, skip the candidate without changing lifecycle labels, without posting "Claimed", and without dispatching the lifecycle. Record it under "Skipped (active blockers)" in the summary and include the active blocker refs. Keep any dependency-hold comment idempotent with a `[claude-build-intake]` prefix.
|
|
477
|
+
|
|
478
|
+
#### 3b. Claim
|
|
479
|
+
|
|
480
|
+
Before the claim mutation, apply `claim-time-guards` — **Value before claim**, or **Worth doing** in `lisa-track` on runtimes without the rule tree (Antigravity). A ready label establishes neither value nor permission to expand scope. Respect the preceding human-hold gate; a declined incidental item consumes this cycle's one processed disposition.
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
**Rejection detection runs first — before the relabel below.** Per the vendor-neutral `rejection-detection` rule (cite the slug; do not restate its classification table), classify this item at the **top of 3b, BEFORE** the `$READY → $CLAIMED` relabel — after the relabel the current-lane signal is gone. Read the item's Label-Event History from `lisa-github-read-issue` (chronological `LabeledEvent` / `UnlabeledEvent` on the configured `$READY` label) and classify it `rejection-reclaim | forward-only | never-left-ready | unknown`. Lane names come from `.lisa.config.json` (`github.labels.build.*`), never hardcoded. A failing/absent history yields `unknown` and the claim proceeds — detection never blocks the build. Items carrying a learning marker (`[lisa-learning-drop]` / `[lisa-learning-pr]` / `[lisa-learning-upstream-handoff]`) or the `learning:needs-triage` label are never rejection triggers (no learning-about-learning). Carry the classification into the relabel and lifecycle below.
|
|
484
|
+
|
|
485
|
+
**On `rejection-reclaim`, reflect before re-implementing** (per `rejection-detection`): read the rejection evidence through the access layer — the issue comments posted after the backward transition (the QA rejection comment) and the review threads on the rejected PR via `lisa-github-read-issue` — assemble ONE candidate learning (rule, why, provenance linking the rejection comment + rejected PR, evidence links, scope hint, triggering issue, fingerprint `sll4-sha1(rule\ntriggering_issue)[:12]`), and route it to the `lisa-persist-learning` skill. If that skill is absent, record the candidate as a comment carrying a **visible prose line plus** the marker (a bare marker renders as an empty bubble) — `Recorded a candidate learning from this rejection (queued for the judgment gate): <one-line candidate rule>.` then `<!-- [lisa-rejection-candidate] key=<issue>-<transition-ts> -->` — and proceed. Dedupe on `<issue>-<backward-transition-timestamp>` — a second re-claim produces no duplicate. Unreadable/absent evidence → no candidate, still implement.
|
|
486
|
+
|
|
487
|
+
**Claim-time archaeology runs second — after rejection detection, still before the relabel below.** Classify this item per the vendor-neutral `claim-archaeology` rule, with the rejection classification above as its input. All shared semantics — ancestry signals, classification, learning-loop exclusion, cost budget, candidate derivation, marker dedupe, and the never-block degrade — live in that one slug; change them there, never here. GitHub wiring only: the typed relations and `closingIssuesReferences` are already in the read bundle; text-similarity searches use `gh search issues` over recently-closed issues; the fallback candidate comment is posted with `gh issue comment`.
|
|
488
|
+
|
|
489
|
+
**The two `claim-time-guards` run third and fourth — still before the relabel below.** Both semantics live in that one vendor-neutral slug; do not restate them here. GitHub wiring only:
|
|
490
|
+
|
|
491
|
+
1. **`two-failed-attempts` valve.** Count `[lisa-build-attempt]` markers on the issue from the read bundle's comments (match on the marker, never the title), applying both filters from `claim-time-guards`: count a marker only when it carries `measures=work` (a marker with no `measures=` counts as `work`), and only when its `createdAt` is **after the issue most recently gained the ready label**. The ready-lane entry comes from the read bundle's `LabeledEvent` stream, which is already fetched — no extra call. If that history is `unknown`, count every `measures=work` marker regardless of age and say so in the comment. With two or more surviving markers, do **not** claim: relabel to the configured blocked role (`gh issue edit <number> --repo <org>/<repo> --remove-label "$READY" --add-label "$BLOCKED"`, resolved from `github.labels.build.blocked` per `config-resolution`), post the operator-readable comment naming both attempts, and **stop the cycle** at Phase 3e. Every non-success terminal outcome recorded in 3c/3d also appends a fresh `<!-- [lisa-build-attempt] n=<N> outcome=<outcome> measures=<work|machine> -->` marker so the next cycle can count it — `measures=machine` when the run was terminated by a signal or its outcome was `recovery-required`, `measures=work` when the build ran and did not satisfy the issue.
|
|
492
|
+
2. **`already-implemented` check.** Probe for this issue's own key — `git log --all --grep "<org>/<repo>#<number>"` and `gh pr list --repo <org>/<repo> --state all --search "<org>/<repo>#<number>" --json number,state,mergedAt,url`. On a hit, claim as normal but route 3c to **verify-and-close** instead of `lisa-implement`: verify what shipped against the issue's acceptance criteria, post evidence via `lisa-github-evidence` naming the shipping PR/commit, then run the ordinary 3d transition and 3d.1 rollup. A partial hit implements only the remaining gap. An unreadable history degrades to "no hit" and the ordinary path proceeds — the guard never blocks the claim. This is not `DUPLICATE_ALREADY_FIXED` (a *different* canonical issue) and not `claim-archaeology` (a *different* ancestor issue); it is this issue's own work already having shipped without a transition.
|
|
493
|
+
|
|
494
|
+
Immediately before claiming, re-read native state. If it is closed, skip it without
|
|
495
|
+
relabeling or dispatching; an unreadable state holds the candidate.
|
|
496
|
+
|
|
497
|
+
```bash
|
|
498
|
+
gh issue view <number> --repo <org>/<repo> --json state -q '.state' # must be OPEN
|
|
499
|
+
gh issue edit <number> --repo <org>/<repo> --remove-label "$READY" --add-label "$CLAIMED"
|
|
500
|
+
# Assign to the authenticated user ONLY when the issue is currently unassigned (attributable claim;
|
|
501
|
+
# do not pile a second assignee onto an issue that already has an owner):
|
|
502
|
+
gh issue view <number> --repo <org>/<repo> --json assignees -q '.assignees | length' # → if 0:
|
|
503
|
+
gh issue edit <number> --repo <org>/<repo> --add-assignee "@me"
|
|
504
|
+
gh issue comment <number> --repo <org>/<repo> --body "[claude-build-intake] Claimed by Claude. Starting build."
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
This is the idempotency lock — a re-entrant cycle's `--label $READY` filter will not see this issue again.
|
|
508
|
+
|
|
509
|
+
If the relabel fails (permission, race), log under "Errors" in the cycle summary and skip this issue. **Do not invoke the build flow on an issue you didn't successfully claim.**
|
|
510
|
+
|
|
511
|
+
#### 3c. Run the per-issue lifecycle in-session (never as a subagent)
|
|
512
|
+
|
|
513
|
+
After the claim succeeds, run the per-issue lifecycle defined by the `github-agent` workflow **in the current session** — never by spawning `github-agent` (or any named worker) via the `Agent` tool. The lifecycle culminates in a team-first flow (`lisa-implement`), and that flow can only create its agent team from the lead session: a spawned teammate cannot add named teammates (Claude teams are flat), so dispatching the build into a subagent strands `lisa-implement` without its team and collapses the build into a single inline worker. Concretely:
|
|
514
|
+
|
|
515
|
+
1. **Run the gates in-session** via their skills, exactly as `github-agent.md` defines them and with all of its gating behaviors intact:
|
|
516
|
+
- `lisa-github-read-issue` — the full issue graph (mandatory; never ad-hoc `gh` reads)
|
|
517
|
+
- `lisa-github-verify` — pre-flight quality gate, including the draft-then-block procedure on FAIL
|
|
518
|
+
- `lisa-ticket-triage` — analytical triage gate (a `BLOCKED` verdict stops the cycle with findings posted)
|
|
519
|
+
- Intent determination from the `type:` label
|
|
520
|
+
2. **Dispatch the flow in-session:** when the gates pass, invoke the lifecycle skill via the Skill tool — `lisa-implement <org>/<repo>#<number>` for Build / Fix / Improve / Investigate-Only (or `lisa-plan` for an Epic) — passing the full context bundle from the read step. Hand that bundle over by file, not by text: before invoking `lisa-implement`, run the ignore guard below, then write the bundle verbatim to persist it at the git-ignored `.lisa/work-item-context.md` of this worktree — always overwriting the file with this cycle's bundle, never reusing one an earlier item left behind — and pass only `caller_bundle_path=<absolute path>` in the invocation. `lisa-implement`'s input-resolver keeps that file as the base instead of re-summarizing it, so every comment reaches the agents doing the work. Bundle text, and any credential value in it, never appears in a spawn prompt, task description, or Skill argument — only its path. **Ignore guard before any write.** A host can receive these skills before its shipped `.gitignore` entry, so prove the path is ignored first, from the worktree root: `git check-ignore -q .lisa/work-item-context.md || printf '%s\n' '.lisa/work-item-context.md' >> "$(git rev-parse --git-common-dir)/info/exclude"`, then re-run `git check-ignore -q .lisa/work-item-context.md`. If it is still not ignored, stop and report — do not write the bundle. If an `.easignore` exists and `grep -qxF '.lisa/work-item-context.md' .easignore` fails, stop and report instead of writing: EAS uploads read `.easignore`, which is derived from `.gitignore`, not from `info/exclude`. **When 3b classified this item `rejection-reclaim`, the context bundle passed to `lisa-implement` MUST include the rejection evidence summary** (what was rejected, the defect the QA comment named, the approach named as wrong) — reuse the evidence already read in 3b, do not fetch it twice — so the plan can address it per `rejection-detection`; absence of evidence never blocks. `lisa-implement`'s own orchestration preamble then creates the per-item agent team (input-resolver, Roster Decision, specialist fanout) exactly as a direct invocation would.
|
|
521
|
+
3. **Milestone sync and evidence** (`lisa-github-sync`, `lisa-github-evidence`) happen at the milestones the `github-agent` workflow defines, within the dispatched flow.
|
|
522
|
+
|
|
523
|
+
If you are somehow running this skill as a spawned teammate inside an existing team (nested misrouting — Intake keeps this chain in the lead session), do NOT run the lifecycle inline and do NOT spawn named peers. Return this payload to the lead so the lead session can run this Phase 3c in-session:
|
|
524
|
+
|
|
525
|
+
```json
|
|
526
|
+
{
|
|
527
|
+
"type": "delegation-request",
|
|
528
|
+
"phase": "github-build-intake 3c",
|
|
529
|
+
"workItem": "<org>/<repo>#<number>",
|
|
530
|
+
"context": {
|
|
531
|
+
"claimedLabel": "$CLAIMED",
|
|
532
|
+
"doneResolution": "Resolve $DONE from the PR base branch per this skill's Workflow resolution section"
|
|
533
|
+
},
|
|
534
|
+
"onSuccess": "Confirm the returned PR is merged, then apply Phase 3d and Phase 3d.1",
|
|
535
|
+
"onBlockedOrError": "Leave the issue where the lifecycle left it and record the surfaced outcome"
|
|
536
|
+
}
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
The lifecycle run returns one of the following outcomes; resume this scanner with it:
|
|
540
|
+
|
|
541
|
+
- **Success** — the build flow completed and a PR exists; evidence posted. The PR may already be **merged** or still **open** (auto-merge enabled, awaiting checks/merge). "Success" means the build work is sound — it does **not** assert the change reached an environment. The env transition in 3d gates on the PR actually being merged; an open PR does not advance the issue to a `done` env status.
|
|
542
|
+
- **Blocked by github-verify pre-flight gate** — the pre-flight gate (github-agent workflow step 2) relabels the issue to `status:blocked` (or removes `$CLAIMED` and reassigns to the original author). This is correct and expected — let it stand. Record and move on.
|
|
543
|
+
- **Duplicate already fixed** — `lisa-ticket-triage` returned `DUPLICATE_ALREADY_FIXED` with a canonical issue reference and empirical base-branch evidence. Follow 3c.1 to link the duplicate, remove lifecycle roles, and close it as not planned without adding a done label or opening a PR. If the canonical fix is merged but not yet on the production branch, the close comment must say the production error can recur until the canonical issue promotes and that recurrence is tracked by the canonical issue; do not reopen this duplicate for that recurrence.
|
|
544
|
+
- **Blocked by ticket-triage ambiguities** — triage posts findings and the lifecycle stops. The issue stays in `$CLAIMED`. Surface to human; do not auto-relabel. Record under "Errors".
|
|
545
|
+
- **Errored** — exception, missing config, etc. Leave the issue in `$CLAIMED` for human investigation. Record under "Errors".
|
|
546
|
+
|
|
547
|
+
#### 3c.1 Close duplicate already fixed
|
|
548
|
+
|
|
549
|
+
Run this only when the returned triage verdict is exactly `DUPLICATE_ALREADY_FIXED`.
|
|
550
|
+
|
|
551
|
+
1. Verify the structured result includes a canonical issue reference, the canonical PR/commit, and empirical evidence that the canonical fix is present on the base branch. If any piece is missing, treat the outcome as Held instead of closing.
|
|
552
|
+
2. Post or preserve the triage-finding comment that explains why this issue is a duplicate and names the canonical issue.
|
|
553
|
+
3. Ensure a native `duplicates <canonical>` link exists when GitHub exposes issue relationships; if this installation cannot create that relationship, leave an explicit issue cross-reference comment/body link and record the limitation in the summary.
|
|
554
|
+
4. Resolve the configured lifecycle role set, including every environment's done value.
|
|
555
|
+
5. Remove every lifecycle role the issue currently carries. Add no done label: this duplicate is being declined, and the canonical issue records delivery. Close as duplicate/not-planned:
|
|
556
|
+
|
|
557
|
+
```bash
|
|
558
|
+
gh issue view <number> --repo <org>/<repo> --json labels -q '[.labels[].name] | join(" ")'
|
|
559
|
+
gh issue edit <number> --repo <org>/<repo> <one --remove-label "<role>" per lifecycle role the issue CURRENTLY carries; skip when none>
|
|
560
|
+
gh issue close <number> --repo <org>/<repo> --reason "not planned"
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
6. **Confirm with an independent readback, and only then announce** — the same obligation as Phase 3d step 5, for the same reason. Re-read the issue instead of trusting what the edit and close reported:
|
|
564
|
+
|
|
565
|
+
```bash
|
|
566
|
+
gh issue view <number> --repo <org>/<repo> --json state,stateReason,labels
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
It must read `state: CLOSED` with `stateReason: NOT_PLANNED` and carry **no** lifecycle role, including `$DONE`. Anything else is an Error naming what is still present. Post the closeout comment only after that passes:
|
|
570
|
+
|
|
571
|
+
```bash
|
|
572
|
+
gh issue comment <number> --repo <org>/<repo> --body "[claude-build-intake] Closed as duplicate of <canonical>. Canonical fix: <PR-or-commit>. Evidence: <base-branch-proof>."
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
If the canonical fix is merged but not yet present on the production branch, append the production-promotion caveat to the close comment: the production error can recur until the canonical issue promotes, and recurrence is tracked by the canonical issue rather than by reopening this duplicate.
|
|
576
|
+
|
|
577
|
+
This path is distinct from `BLOCKED`: ambiguity, open blockers, and duplicate-of-open findings remain held for human action and must not be auto-closed.
|
|
578
|
+
|
|
579
|
+
#### 3c.2 Confirm applied learnings (last_confirmed bump)
|
|
580
|
+
|
|
581
|
+
Run this at the end of 3c, after the lifecycle outcome is recorded and before 3d. It keeps the decay pass safe: a genuinely useful learning that keeps applying stays fresh, while dead weight ages out.
|
|
582
|
+
|
|
583
|
+
1. **Identify which learnings demonstrably applied.** Resolve the learnings surface with `resolveProjectLearningsFile` and parse it with `parseLearningsFile` from `@codyswann/lisa/learnings` (never hardcode the path; a missing file skips this step silently). An entry counts as applied ONLY when its rule was explicitly cited or observably followed in this claim's plan, diff, or review responses — the plan quotes the rule or its id, or the diff does specifically what the rule mandates where the default behavior would have differed. **Presence in context is NOT application**: entries reach a session only through the contract's bounded projection, so counting "it was projected" would confirm every projected entry on every claim and defeat decay entirely. A run that produced no plan or diff has nothing to confirm.
|
|
584
|
+
2. **Bump each applied entry exactly once** via the surgical writer:
|
|
585
|
+
|
|
586
|
+
```bash
|
|
587
|
+
node -e 'import("@codyswann/lisa/learnings").then(async m => { const r = await m.confirmLearningEntry(process.cwd(), process.argv[1], new Date().toISOString().slice(0, 10)); console.log(JSON.stringify(r)); }).catch(error => { console.log(JSON.stringify({ status: "error", id: process.argv[1], message: String(error) })); })' <entry-id> || true
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
The invocation is failure-safe by construction: a rejected import or write resolves to a structured `error` result instead of a crash, and the trailing `|| true` absorbs any remaining non-zero exit (missing `node`, unresolvable package). Record an `error` or non-zero outcome in the cycle summary and continue — the bump must never abort the lifecycle.
|
|
591
|
+
|
|
592
|
+
`confirmLearningEntry` advances ONLY `last_confirmed` — rule text, why, provenance, `first_learned`, and confidence are untouched — and is idempotent within a claim: a repeat same-date bump returns `unchanged`, so an entry that applied repeatedly during one claim is bumped once, not once per application.
|
|
593
|
+
3. **Never block on it.** A failed bump, an unwritable file, or a `not-found` result (the entry was pruned) is recorded under the cycle summary and the claim proceeds — shipping the issue always outranks confirming a learning about it.
|
|
594
|
+
|
|
595
|
+
#### 3d. Transition to $DONE (only after the PR is merged)
|
|
596
|
+
|
|
597
|
+
A `done` env state (`status:on-dev`, `status:on-stg`, or the terminal value) asserts that the code has actually reached that environment. Never set it for a PR that is merely open: auto-merge can be blocked indefinitely (a required rebase / `BEHIND` branch, failing checks, an unaddressed review), and the change may never land. Relabeling an issue `status:on-stg` on an open PR makes it *claim* a deploy that never happened. Transition only after confirming the PR merged.
|
|
598
|
+
|
|
599
|
+
If the lifecycle run returned Success:
|
|
600
|
+
|
|
601
|
+
1. **Confirm the PR merged.** Read the live state of the issue's PR — `gh pr view <pr> --json state,mergedAt,mergeStateStatus,url`:
|
|
602
|
+
- **Merged** (`state == MERGED`) → proceed to resolve and apply `$DONE` below. Where the env deploy is observable (a deploy workflow run / deployment status keyed to the merged-into branch via `deploy.branches`), run the **promotion-completeness gate** (resolution step 5) across **every** env branch at or below the resolved env — not only the merged-into branch. A rung counts only when the merge commit is an ancestor of its branch **and** that branch's most recent deploy concluded `success`; a still-running or otherwise unconcluded deploy is treated like an open PR (leave in `$CLAIMED`), and a rung whose deploy concluded anything but `success` is recorded as an Error. Where a branch exposes no deploy surface at all, ancestry alone decides that rung.
|
|
603
|
+
- **Open / not yet merged** → do **not** transition. The build is sound but the change has reached no environment yet. Record the issue under **"PR open — awaiting merge"** in the summary (with the PR URL and its `mergeStateStatus`), leave it in `$CLAIMED`, and stop. A later `lisa-repair-intake` cycle drives the open PR to merge — re-syncing a `BEHIND` branch so the already-enabled auto-merge can land, or surfacing a real blocker — and, once merged, applies this same env transition. Do **not** comment "Build complete" or close anything.
|
|
604
|
+
- **Closed without merging** → record an Error (the PR was abandoned unmerged); leave the issue in `$CLAIMED`.
|
|
605
|
+
2. Resolve `$DONE` for this issue's PR base branch using the Workflow resolution algorithm above, **including its promotion-completeness cap** (step 5): the value written is the highest contiguously reached rung at or below the resolved env, never the resolved env by itself. If env can't be resolved and `done` is env-keyed, record an Error and skip this transition — never guess.
|
|
606
|
+
3. Determine whether `$DONE` is the true terminal done value per the `leaf-only-lifecycle` rule's Terminal native closure section:
|
|
607
|
+
- If `github.labels.build.done` is a string, that string is terminal.
|
|
608
|
+
- If `github.labels.build.done` is an object, only the production/final environment value is terminal (default: `status:done`). Intermediate env values such as `status:on-dev` and `status:on-stg` are not terminal and must stay open.
|
|
609
|
+
- If the project uses a different final environment name, resolve it from the configured deployment topology; if ambiguous, record an Error and do not close.
|
|
610
|
+
|
|
611
|
+
4. **Retire every competing lifecycle role**, per the `leaf-only-lifecycle` rule's "Exactly one lifecycle role survives closure" — cite it, do not restate it. Read the issue's current labels, intersect them with the configured role set (`$READY`, `$CLAIMED`, `$BLOCKED`, `$REVIEW` where bound, and every env-keyed done value), and remove each one that is present except `$DONE`. Removing only `$CLAIMED` leaves a stale `$READY` on any item that reached completion without passing through the claimed lane, and a closed item still reading ready is re-dispatched by this very scanner on its next cycle.
|
|
612
|
+
|
|
613
|
+
```bash
|
|
614
|
+
gh issue view <number> --repo <org>/<repo> --json labels -q '[.labels[].name] | join(" ")'
|
|
615
|
+
gh issue edit <number> --repo <org>/<repo> --add-label "$DONE" <one --remove-label "<role>" per competing role the issue CURRENTLY carries>
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
Name only roles the read actually returned: `--remove-label` on a label the issue does not carry is a 404, which turns a clean transition into an error and makes a repeat cycle fail where the first succeeded.
|
|
619
|
+
|
|
620
|
+
If `$DONE` is terminal, immediately close the native GitHub issue:
|
|
621
|
+
|
|
622
|
+
```bash
|
|
623
|
+
gh issue close <number> --repo <org>/<repo> --reason completed
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
This close is idempotent: if the issue is already closed, record that native closure was already satisfied and continue. If `$DONE` is an intermediate env state, leave the issue open by design.
|
|
627
|
+
|
|
628
|
+
5. **Confirm with an independent readback, and only then announce.** Re-read the issue rather than trusting what the edit and close commands reported about themselves:
|
|
629
|
+
|
|
630
|
+
```bash
|
|
631
|
+
gh issue view <number> --repo <org>/<repo> --json state,stateReason,labels
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
The item must carry `$DONE` and **no** other lifecycle role, and — when `$DONE` is terminal — read `state: CLOSED`. Anything else is recorded as an Error naming the roles still present; do not report the transition as applied on the strength of a write that said it worked.
|
|
635
|
+
|
|
636
|
+
Post the completion comment **only after** that readback passes:
|
|
637
|
+
|
|
638
|
+
```bash
|
|
639
|
+
gh issue comment <number> --repo <org>/<repo> --body "[claude-build-intake] Build complete. PR <URL> merged. Transitioned to $DONE."
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
The ordering is the point. Announcing before verifying leaves a public "Build complete" on an item whose lifecycle state was never confirmed, and a reader has no way to tell that claim apart from a verified one — the same indistinguishability the readback exists to prevent. On a failed readback, comment the Error instead.
|
|
643
|
+
|
|
644
|
+
`node scripts/lisa-work-item.mjs complete --ref <org>/<repo>#<number>` performs this whole terminal sequence — merged-PR evidence check, full role reconciliation, close, independent readback — in one step, and is the preferred path whenever `$DONE` is the terminal value. It also decides for itself whether `$DONE` is terminal here: it resolves each merged PR's base branch through `.lisa.config.json` `deploy.branches`, so a merge into an intermediate env branch records that env's role WITHOUT closing the issue, and a merge into a branch the project does not deploy records nothing and says which base it saw. The manual commands above remain available for an intermediate env transition performed without merge evidence.
|
|
645
|
+
|
|
646
|
+
For any non-Success outcome, do NOT transition. The issue sits in `$CLAIMED` (or wherever the lifecycle left it) — humans take it from there.
|
|
647
|
+
|
|
648
|
+
#### 3d.1 Roll up the parent chain (forward rollup)
|
|
649
|
+
|
|
650
|
+
Run this **only after a successful `$DONE` transition in 3d** (the leaf actually reached an env — intermediate or terminal). This is the **forward** arm of the `leaf-only-lifecycle` rule's *"rollup is evaluated whenever a child transitions"* requirement: a leaf reaching `$DONE` is exactly such a transition, so its parent's derived state may now have changed — the last open child of a Story just shipped, so the Story rolls up to `$DONE` and closes, which may in turn complete its Epic. Without this step a fully-built parent stays open until the recovery `lisa-repair-intake` cron happens to run.
|
|
651
|
+
|
|
652
|
+
1. Resolve the leaf's parent using the same hierarchy `lisa-github-read-issue` uses — native sub-issue parent first (GraphQL `parent`), then body parentage (`Parent: #<n>` / `Parent Epic: #<n>`). If the leaf has no parent, skip — nothing to roll up.
|
|
653
|
+
2. Walk **up the ancestor chain bottom-up**: for the immediate parent, then its parent, and so on, invoke `lisa-github-sync <org>/<repo>#<ancestor> --rollup`. That skill derives the ancestor's `status:*` from its children per `leaf-only-lifecycle`, applies it only when it differs (never `status:ready`), and performs terminal native closure (`gh issue close --reason completed`) when the derived env is the production/terminal `$DONE`. It is idempotent and safe-defaults (suggests, does not guess) when the rolled state is ambiguous.
|
|
654
|
+
3. Stop walking up when an ancestor has no parent, or when `--rollup` reports no change (a higher ancestor cannot advance past an unchanged child). Record each rolled-up ancestor and its derived state in the summary.
|
|
655
|
+
|
|
656
|
+
This does not re-implement the state machine — it delegates to `lisa-github-sync --rollup`, the single rollup implementation `lisa-repair-intake` also uses, so the forward and recovery paths can never drift. Children closed **outside** this flow (e.g. by external automation) are not observed here; `lisa-repair-intake` remains the recovery net for those.
|
|
657
|
+
|
|
658
|
+
#### 3e. Stop
|
|
659
|
+
|
|
660
|
+
Stop immediately after the first claimed, skipped, blocked, held, or errored issue. Later scheduler invocations process the remaining ready issues.
|
|
661
|
+
|
|
662
|
+
### Phase 4 — Summary report
|
|
663
|
+
|
|
664
|
+
```text
|
|
665
|
+
## github-build-intake summary
|
|
666
|
+
|
|
667
|
+
Repo: <org>/<repo>
|
|
668
|
+
Cycle started: <ISO timestamp>
|
|
669
|
+
Cycle completed: <ISO timestamp>
|
|
670
|
+
|
|
671
|
+
Issues processed: <n>
|
|
672
|
+
- $DONE (build complete, PR merged): <n>
|
|
673
|
+
- <org>/<repo>#<number> <title> → PR <URL>
|
|
674
|
+
- PR open — awaiting merge (left in $CLAIMED for repair-intake): <n>
|
|
675
|
+
- <org>/<repo>#<number> <title> → PR <URL> (mergeStateStatus: <state>)
|
|
676
|
+
- Repaired (container — leaf-only-lifecycle): <n>
|
|
677
|
+
- <org>/<repo>#<number> <title> — build-ready on a parent/container; moved $READY → $CLAIMED without dispatching the lifecycle; lifecycle-repair comment posted
|
|
678
|
+
- Skipped (active blockers): <n>
|
|
679
|
+
- <org>/<repo>#<number> <title> — waiting on <blocker refs>
|
|
680
|
+
- Duplicate already fixed (closed as duplicate): <n>
|
|
681
|
+
- <org>/<repo>#<number> <title> — duplicate of <canonical>; no PR opened
|
|
682
|
+
- Blocked (pre-flight verify failed): <n>
|
|
683
|
+
- <org>/<repo>#<number> <title> — see issue comments
|
|
684
|
+
- Held (triage found ambiguities): <n>
|
|
685
|
+
- <org>/<repo>#<number> <title> — see issue comments
|
|
686
|
+
- Errors: <n>
|
|
687
|
+
- <org>/<repo>#<number> <title> — <reason>
|
|
688
|
+
|
|
689
|
+
Total PRs opened: <n>
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
## Idempotency & safety
|
|
693
|
+
|
|
694
|
+
- **Leaf-only claim gate runs first**: Phase 3a classifies each candidate before any leaf claim; a container with open child work (or a childless Epic) is moved `$READY` → `$CLAIMED` as lifecycle repair and never dispatched. The lifecycle-repair comment is idempotent — a re-entrant cycle does not re-post it.
|
|
695
|
+
- **Dependency hold runs before leaf claim**: explicit `Blocked by:` relationships are resolved after container repair is ruled out but before `$READY → $CLAIMED`; active blockers leave the leaf candidate in `$READY` and are reported as skipped, not blocked.
|
|
696
|
+
- **Claim-first ordering**: `$CLAIMED` set BEFORE the lifecycle dispatch for leaves; containers are also moved to `$CLAIMED` to leave the ready pickup queue, but are not dispatched.
|
|
697
|
+
- **No writes outside the lifecycle**: this skill only relabels `$READY → $CLAIMED` and `$CLAIMED → $DONE`. For containers, `$READY → $CLAIMED` is a lifecycle repair, not a direct build claim. Every other label change is owned by the per-issue lifecycle (github-agent workflow).
|
|
698
|
+
- **Duplicate terminal exception**: `DUPLICATE_ALREADY_FIXED` is the only triage outcome that may close a claimed item without a PR from this cycle. It must include a canonical issue reference and empirical base-branch evidence, and it closes as duplicate/not-planned rather than as completed build work.
|
|
699
|
+
- **Terminal native closure**: after applying `$DONE` and retiring every competing lifecycle role (`leaf-only-lifecycle`, "Exactly one lifecycle role survives closure"), close the GitHub issue only when `$DONE` is the true terminal done value per `leaf-only-lifecycle`; intermediate env labels stay open. Confirm the result with an independent readback, never with the write's own response.
|
|
700
|
+
- **One item per cycle**: per-issue exceptions are caught and recorded, then the cycle exits. The scheduler owns retrying or moving on to the next ready item.
|
|
701
|
+
- **Single cycle per repo**: do not run two `lisa-github-build-intake` cycles in parallel against the same repo — concurrent claims could race. The scheduling layer is responsible for serialization.
|
|
702
|
+
- **Single-label invariant**: after every transition, verify exactly one `status:*` label is present on the issue. If two are present (rare race), surface as an Error and skip — do NOT auto-resolve.
|
|
703
|
+
- **Never pick an arbitrary env for `$DONE`**. If `done` is a map and env is ambiguous, fail loudly.
|
|
704
|
+
|
|
705
|
+
## Configuration
|
|
706
|
+
|
|
707
|
+
| Variable | Default | Purpose |
|
|
708
|
+
|----------|---------|---------|
|
|
709
|
+
| `.lisa.config.json` `github.org` | (from `$ARGUMENTS`) | GitHub org for the default queue |
|
|
710
|
+
| `.lisa.config.json` `github.repo` | (from `$ARGUMENTS`) | Current code-repo identity and `repo:<current>` scope |
|
|
711
|
+
| `.lisa.config.json` `github.queueRepo` | `github.org/github.repo` | Default GitHub scan repo when no explicit repo/URL is passed |
|
|
712
|
+
| `.lisa.config.json` `github.labels.build.ready` | `status:ready` | The label that signals "human says this is buildable" |
|
|
713
|
+
| `.lisa.config.json` `github.labels.build.claimed` | `status:in-progress` | The label set on pickup |
|
|
714
|
+
| `.lisa.config.json` `github.labels.build.done` | env-keyed map or string | The label set after a successful build; env-aware |
|
|
715
|
+
| `.lisa.config.json` `deploy.branches` | — | Reverse-lookup map for env inference from PR base branch |
|
|
716
|
+
|
|
717
|
+
If the repo has not adopted the `status:*` label namespace, this skill cannot run. The remediation is to create the labels — `gh label create status:ready --color FBCA04 --description "Ready for build"` and similar — typically a one-time setup. See "Adoption" below for the full command set using the defaults; if your project overrides the role names, substitute accordingly.
|
|
718
|
+
|
|
719
|
+
## Rules
|
|
720
|
+
|
|
721
|
+
- **Dispatch leaves only.** Per the `leaf-only-lifecycle` rule, never dispatch a container — an issue with open child work, or a childless Epic — even if it carries the build-ready role. Move it `$READY → $CLAIMED` as lifecycle repair (Phase 3a); never silently implement a container.
|
|
722
|
+
- Never relabel an issue outside the cycle's allowed transitions. The `$CLAIMED` label is the signature of cycle ownership for leaves, and the parent/container progress state for lifecycle repairs.
|
|
723
|
+
- Never do build work directly from this scanner — the per-issue lifecycle (the `github-agent` workflow culminating in `lisa-implement`) owns it. And never spawn that lifecycle as a subagent; run it in-session per Phase 3c so `lisa-implement` can create its agent team.
|
|
724
|
+
- Never auto-transition past `$DONE`. Downstream labels (terminal `status:done`, etc.) are owned by QA / PM / merge automation.
|
|
725
|
+
- Never close a GitHub issue at intermediate env states (`status:on-dev`, `status:on-stg`, or configured equivalents). Native close happens only at the terminal `done` value.
|
|
726
|
+
- Never auto-close a `BLOCKED`, ambiguous, or duplicate-of-open issue. Auto-close is allowed only for `DUPLICATE_ALREADY_FIXED`.
|
|
727
|
+
- If the issue has no Validation Journey or no sign-in credentials, the pre-flight verify gate will catch it — **don't try to fix the issue from here**.
|
|
728
|
+
- On any unexpected outcome from the lifecycle run (status it doesn't claim, missing PR URL on success), record as Error and surface — never assume.
|
|
729
|
+
- Never pick an arbitrary env for `$DONE` resolution. If `done` is a map and env is ambiguous, fail loudly.
|
|
730
|
+
|
|
731
|
+
## Adoption (one-time per repo)
|
|
732
|
+
|
|
733
|
+
Before this skill can run, the repo must adopt the `status:*` label namespace. Using the defaults:
|
|
734
|
+
|
|
735
|
+
1. Create the labels:
|
|
736
|
+
```bash
|
|
737
|
+
gh label create status:ready --color FBCA04 --description "Ready for build" --repo <org>/<repo>
|
|
738
|
+
gh label create status:in-progress --color 0E8A16 --description "Build in progress" --repo <org>/<repo>
|
|
739
|
+
gh label create status:on-dev --color 1D76DB --description "Built, deployed to dev" --repo <org>/<repo>
|
|
740
|
+
gh label create status:done --color 0E8A16 --description "Shipped" --repo <org>/<repo>
|
|
741
|
+
```
|
|
742
|
+
If your project overrides any `github.labels.build.*` role name in config, substitute the actual label names you configured.
|
|
743
|
+
2. Apply the `$READY` label to issues that are ready for development.
|
|
744
|
+
3. Reserve `$CLAIMED`, `$DONE` for this skill — humans should not set them manually except to recover from an error.
|
|
745
|
+
4. PRD-source labels (defaults: `prd-ready`, `prd-in-review`, etc.) are a SEPARATE namespace owned by `lisa-github-prd-intake`. Don't conflate.
|