@codyswann/lisa 2.174.0 → 2.175.0
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/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/commands/monitor.md +3 -3
- package/plugins/lisa/rules/eager/leaf-only-lifecycle.md +2 -0
- package/plugins/lisa/rules/eager/observability-audit.md +15 -0
- package/plugins/lisa/rules/reference/config-resolution.md +35 -0
- package/plugins/lisa/rules/reference/intent-routing.md +8 -3
- package/plugins/lisa/rules/reference/leaf-only-lifecycle.md +1 -0
- package/plugins/lisa/rules/reference/observability-audit.md +122 -0
- package/plugins/lisa/skills/github-build-intake/SKILL.md +25 -0
- package/plugins/lisa/skills/intake/SKILL.md +1 -0
- package/plugins/lisa/skills/jira-build-intake/SKILL.md +19 -0
- package/plugins/lisa/skills/linear-build-intake/SKILL.md +19 -0
- package/plugins/lisa/skills/monitor/SKILL.md +27 -6
- package/plugins/lisa/skills/monitor/agents/openai.yaml +2 -2
- package/plugins/lisa/skills/ticket-triage/SKILL.md +10 -6
- package/plugins/lisa/skills/tracker-build-intake/SKILL.md +21 -0
- package/plugins/lisa/skills/tracker-verify/SKILL.md +1 -0
- package/plugins/lisa/skills/verify/SKILL.md +1 -1
- package/plugins/lisa-agy/commands/monitor.md +3 -3
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/github-build-intake/SKILL.md +25 -0
- package/plugins/lisa-agy/skills/intake/SKILL.md +1 -0
- package/plugins/lisa-agy/skills/jira-build-intake/SKILL.md +19 -0
- package/plugins/lisa-agy/skills/linear-build-intake/SKILL.md +19 -0
- package/plugins/lisa-agy/skills/monitor/SKILL.md +27 -6
- package/plugins/lisa-agy/skills/ticket-triage/SKILL.md +10 -6
- package/plugins/lisa-agy/skills/tracker-build-intake/SKILL.md +21 -0
- package/plugins/lisa-agy/skills/tracker-verify/SKILL.md +1 -0
- package/plugins/lisa-agy/skills/verify/SKILL.md +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-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/commands/monitor.md +3 -3
- package/plugins/lisa-copilot/rules/eager/leaf-only-lifecycle.md +2 -0
- package/plugins/lisa-copilot/rules/eager/observability-audit.md +15 -0
- package/plugins/lisa-copilot/rules/reference/config-resolution.md +35 -0
- package/plugins/lisa-copilot/rules/reference/intent-routing.md +8 -3
- package/plugins/lisa-copilot/rules/reference/leaf-only-lifecycle.md +1 -0
- package/plugins/lisa-copilot/rules/reference/observability-audit.md +122 -0
- package/plugins/lisa-copilot/skills/github-build-intake/SKILL.md +25 -0
- package/plugins/lisa-copilot/skills/intake/SKILL.md +1 -0
- package/plugins/lisa-copilot/skills/jira-build-intake/SKILL.md +19 -0
- package/plugins/lisa-copilot/skills/linear-build-intake/SKILL.md +19 -0
- package/plugins/lisa-copilot/skills/monitor/SKILL.md +27 -6
- package/plugins/lisa-copilot/skills/ticket-triage/SKILL.md +10 -6
- package/plugins/lisa-copilot/skills/tracker-build-intake/SKILL.md +21 -0
- package/plugins/lisa-copilot/skills/tracker-verify/SKILL.md +1 -0
- package/plugins/lisa-copilot/skills/verify/SKILL.md +1 -1
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/commands/monitor.md +3 -3
- package/plugins/lisa-cursor/rules/config-resolution-reference.mdc +35 -0
- package/plugins/lisa-cursor/rules/intent-routing-reference.mdc +8 -3
- package/plugins/lisa-cursor/rules/leaf-only-lifecycle-reference.mdc +1 -0
- package/plugins/lisa-cursor/rules/leaf-only-lifecycle.mdc +2 -0
- package/plugins/lisa-cursor/rules/observability-audit-reference.mdc +127 -0
- package/plugins/lisa-cursor/rules/observability-audit.mdc +20 -0
- package/plugins/lisa-cursor/skills/github-build-intake/SKILL.md +25 -0
- package/plugins/lisa-cursor/skills/intake/SKILL.md +1 -0
- package/plugins/lisa-cursor/skills/jira-build-intake/SKILL.md +19 -0
- package/plugins/lisa-cursor/skills/linear-build-intake/SKILL.md +19 -0
- package/plugins/lisa-cursor/skills/monitor/SKILL.md +27 -6
- package/plugins/lisa-cursor/skills/ticket-triage/SKILL.md +10 -6
- package/plugins/lisa-cursor/skills/tracker-build-intake/SKILL.md +21 -0
- package/plugins/lisa-cursor/skills/tracker-verify/SKILL.md +1 -0
- package/plugins/lisa-cursor/skills/verify/SKILL.md +1 -1
- 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-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-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-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-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-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-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-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/src/base/commands/monitor.md +3 -3
- package/plugins/src/base/rules/eager/leaf-only-lifecycle.md +2 -0
- package/plugins/src/base/rules/eager/observability-audit.md +15 -0
- package/plugins/src/base/rules/reference/config-resolution.md +35 -0
- package/plugins/src/base/rules/reference/intent-routing.md +8 -3
- package/plugins/src/base/rules/reference/leaf-only-lifecycle.md +1 -0
- package/plugins/src/base/rules/reference/observability-audit.md +122 -0
- package/plugins/src/base/skills/github-build-intake/SKILL.md +25 -0
- package/plugins/src/base/skills/intake/SKILL.md +1 -0
- package/plugins/src/base/skills/jira-build-intake/SKILL.md +19 -0
- package/plugins/src/base/skills/linear-build-intake/SKILL.md +19 -0
- package/plugins/src/base/skills/monitor/SKILL.md +27 -6
- package/plugins/src/base/skills/ticket-triage/SKILL.md +10 -6
- package/plugins/src/base/skills/tracker-build-intake/SKILL.md +21 -0
- package/plugins/src/base/skills/tracker-verify/SKILL.md +1 -0
- package/plugins/src/base/skills/verify/SKILL.md +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.175.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.175.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, across Claude and Codex.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.175.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.175.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.175.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "Monitor application health
|
|
3
|
-
argument-hint: "[environment]"
|
|
2
|
+
description: "Monitor application health AND audit observability completeness for the current repo, then file build-ready tickets for anomalies and instrumentation gaps. Health/logs/errors/performance via the stack ops-specialist or stack-agnostic base probing; repo-scoped, idempotent, capped; files by default, --dry-run previews."
|
|
3
|
+
argument-hint: "[environment] [--dry-run] [--report-only] [--all-gaps] [max_candidates=<n>]"
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
Use the /lisa:monitor skill to check application health, logs, errors, and performance for the named environment. $ARGUMENTS
|
|
6
|
+
Use the /lisa:monitor skill to check application health, logs, errors, and performance for the named environment, audit observability completeness, and file build-ready tickets for the anomalies and gaps it finds. Use `--dry-run` to preview without filing, `--report-only` for a health/audit summary with no filing, or `--all-gaps` to also file recommended-tier gaps (session replay, product analytics). $ARGUMENTS
|
|
@@ -38,4 +38,6 @@ When a leaf reaches the true terminal `done` (the production / final-env value),
|
|
|
38
38
|
|
|
39
39
|
Intermediate env-keyed states (`status:on-dev`, `On Stg`, etc.) remain open. Idempotent — if already closed, report and continue.
|
|
40
40
|
|
|
41
|
+
Duplicate closeout is a narrow terminal exception: build intake may close a claimed item without a PR only when `ticket-triage` returns `DUPLICATE_ALREADY_FIXED` with a canonical item reference and empirical base-branch proof. Close it through provider duplicate semantics, not as completed build work. `BLOCKED`, ambiguous, duplicate-of-open, and other human-owned dispositions are not auto-closed.
|
|
42
|
+
|
|
41
43
|
Full vendor mechanics + the state machine in prose: [reference/leaf-only-lifecycle.md](../reference/leaf-only-lifecycle.md).
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Observability Audit (load-bearing)
|
|
2
|
+
|
|
3
|
+
The **audit + file** arm of `lisa:monitor`. On top of its existing live-signal sweep, `monitor` audits how well the **current repo** is instrumented and files build-ready tickets for what it finds. `monitor` is **manual** (no cron) and **files only** — it never fixes; the `intake` / `tracker-build-intake` cron implements what it files.
|
|
4
|
+
|
|
5
|
+
## Invariants
|
|
6
|
+
|
|
7
|
+
- **Repo-scoped two ways.** Audit only the rubric dimensions in scope for the repo's detected profile (`frontend` / `backend` / `infra` — a frontend repo never evaluates backend tracing), and stamp every filed ticket `repo:<CURRENT_REPO>` as a single-repo leaf (resolve the repo via the `config-resolution` ladder; cannot resolve → report, do not file).
|
|
8
|
+
- **Two finding types → build-ready leaves.** A live signal over the conservative bar → a `Bug` leaf; an in-scope MISSING instrumentation dimension (gap, e.g. "no DB/query analytics") → a `Task`/`Improvement` leaf. Always via `lisa:tracker-write` with `build_ready: true` (never a vendor write skill directly); never an Epic/container (gate S15).
|
|
9
|
+
- **Conservative by default.** Only high-signal anomalies (over the documented thresholds) and `core` missing dimensions are filed. `--all-gaps` widens gap filing to `recommended` tiers; nothing lowers the anomaly bar.
|
|
10
|
+
- **Idempotent.** Every ticket carries a `<!-- lisa-monitor-finding: <fingerprint> -->` sentinel; search-before-create (including closed tickets) means a re-run never duplicates a live or just-resolved finding.
|
|
11
|
+
- **Capped.** At most `monitor.maxCandidates` tickets per run (default 20), highest-severity first; report filed-vs-dropped (and list the dropped) — never silently truncate.
|
|
12
|
+
- **Gate-passing.** Each ticket is a real authored artifact: three-audience description, Gherkin AC, single-repo, Target Backend Environment, and a Validation Journey with a unique kebab-case `[EVIDENCE: <name>]` marker — so `tracker-validate` (S1–S15) accepts it. A finding that cannot be made into a credible ticket is reported, not filed.
|
|
13
|
+
- **Verify guard.** When `monitor` is the post-deploy step of `lisa:verify` it runs **report-only** — Verify invokes it as `lisa:monitor <env> --report-only`, so it never files there. Filing is a standalone-only action.
|
|
14
|
+
|
|
15
|
+
Full reference (profile detection, the rubric table, anomaly thresholds, ticket templates, idempotency contract, the cap, dry-run/report-only semantics): [reference/observability-audit.md](../reference/observability-audit.md).
|
|
@@ -156,6 +156,18 @@ fi
|
|
|
156
156
|
"staleAfterHours": 2,
|
|
157
157
|
"maxCandidates": 100
|
|
158
158
|
}
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
"monitor": {
|
|
162
|
+
"maxCandidates": 20,
|
|
163
|
+
"gapTiers": "core",
|
|
164
|
+
"backoffHours": 24,
|
|
165
|
+
"thresholds": {
|
|
166
|
+
"sentryMinEvents24h": 10,
|
|
167
|
+
"errorRateSpikeMultiplier": 2,
|
|
168
|
+
"p95LatencyMs": 1000,
|
|
169
|
+
"xrayFaultRatePct": 5
|
|
170
|
+
}
|
|
159
171
|
}
|
|
160
172
|
}
|
|
161
173
|
```
|
|
@@ -360,6 +372,29 @@ documented defaults, so existing projects need no config change.
|
|
|
360
372
|
| `intake.repair.staleAfterHours` | no | `2` | How long an in-progress item (build `claimed`, PRD `in_review`) may show no observable activity before repair-intake treats it as stalled and resumes it. `blocked` items are judged on blocker/answer state, not this threshold. Overridable per-run via `stale_after=<dur>` in `$ARGUMENTS` (which always wins). The same value is the default backoff window for loop-prevention notes. |
|
|
361
373
|
| `intake.repair.maxCandidates` | no | `100` | Upper bound on how many stuck items repair-intake enumerates while searching for the first actionable one. Bounds scan cost. Overridable per-run via `max_candidates=<n>`. |
|
|
362
374
|
|
|
375
|
+
### Monitor audit config (`monitor`)
|
|
376
|
+
|
|
377
|
+
`lisa:monitor`'s audit-and-file arm reads an optional top-level `monitor` block. Every key is
|
|
378
|
+
**optional** — a missing block inherits the documented defaults, so existing projects need no
|
|
379
|
+
config change. The role SEMANTICS (what counts as an anomaly or gap, how findings become tickets)
|
|
380
|
+
are fixed like every other lifecycle behavior; only these thresholds and caps are tunable. Full
|
|
381
|
+
contract: the `observability-audit` rule.
|
|
382
|
+
|
|
383
|
+
| Key | Required | Default | Notes |
|
|
384
|
+
|-----|----------|---------|-------|
|
|
385
|
+
| `monitor.maxCandidates` | no | `20` | Cap on tickets filed per standalone run (`core`/high-severity first). Overridable per-run via `max_candidates=<n>` in `$ARGUMENTS`, which always wins. |
|
|
386
|
+
| `monitor.gapTiers` | no | `core` | Which gap tier files tickets by default: `core` (operationally load-bearing dimensions only) or `all` (also `recommended`). The `--all-gaps` run flag forces `all` for that invocation. |
|
|
387
|
+
| `monitor.backoffHours` | no | `24` | How long after a finding's ticket is closed/resolved to keep suppressing a re-file (the recently-resolved dedup window), so a just-fixed regression isn't re-filed before its signal drains. Distinct from `intake.repair.staleAfterHours` (2h). |
|
|
388
|
+
| `monitor.thresholds.sentryMinEvents24h` | no | `10` | Minimum 24h event count for an unresolved Sentry error to be fileable. |
|
|
389
|
+
| `monitor.thresholds.errorRateSpikeMultiplier` | no | `2` | Error rate must be ≥ this × the prior-window baseline (and above an absolute floor) to file. |
|
|
390
|
+
| `monitor.thresholds.p95LatencyMs` | no | `1000` | p95 latency at/above this (or up ≥ 50% vs prior window) is a fileable regression. |
|
|
391
|
+
| `monitor.thresholds.xrayFaultRatePct` | no | `5` | X-Ray fault traces above this % of traces in the window is a fileable anomaly. |
|
|
392
|
+
|
|
393
|
+
Resolution order matches every other key: `$ARGUMENTS` override → `.lisa.config.local.json` →
|
|
394
|
+
`.lisa.config.json` → built-in default. `monitor` files only within the current repo (type-scoped
|
|
395
|
+
rubric + `repo:<name>` single-repo leaves); it never fixes — the `intake` cron implements what it
|
|
396
|
+
files.
|
|
397
|
+
|
|
363
398
|
### Intake assignee filter (`intake.assignee`)
|
|
364
399
|
|
|
365
400
|
The optional intake assignee filter narrows **ready-item selection only**. It never assigns or
|
|
@@ -314,11 +314,16 @@ Sequence:
|
|
|
314
314
|
|
|
315
315
|
### Monitor
|
|
316
316
|
|
|
317
|
-
Purpose: Check application health and operational status. Can be invoked standalone or as
|
|
317
|
+
Purpose: Check application health and operational status, **audit observability completeness**, and (standalone only) **file build-ready tickets** for anomalies and instrumentation gaps. Repo-scoped and manual — there is no cron for Monitor. Can be invoked standalone or as the post-deploy step of Verify.
|
|
318
318
|
|
|
319
319
|
Sequence:
|
|
320
|
-
1.
|
|
321
|
-
2.
|
|
320
|
+
1. **Discover** -- stack-agnostic detection of the repo's observability profile (`frontend` / `backend` / `infra`) and which observability tools are actually wired (read manifests/config; probe only with available credentials). See the `observability-audit` rule.
|
|
321
|
+
2. **Collect live signals** -- `ops-specialist` (Expo/Rails) or inline base probing (Sentry CLI/REST, CloudWatch, X-Ray, Playwright MCP) for health, logs, errors, performance. An observation is a fileable **anomaly** only when it clears the conservative thresholds in `observability-audit`.
|
|
322
|
+
3. **Audit completeness** -- score the repo against the `observability-audit` rubric for its profile; each in-scope MISSING dimension is a **gap** finding (`core` always; `recommended` only with `--all-gaps`).
|
|
323
|
+
4. **Report** -- health/anomaly summary + audit table. Always produced.
|
|
324
|
+
5. **File (standalone only; SKIP under `--report-only`/`--dry-run` and when invoked from Verify)** -- for each anomaly and gap, dedupe by fingerprint (sentinel + search-before-create incl. closed tickets), then file a single-repo build-ready leaf via `tracker-write` (`build_ready: true`) — a `Bug` for an anomaly, a `Task`/`Improvement` for a gap — stamped `repo:<current>`, capped at `max_candidates` (default 20, `core`/high-severity first; list any dropped). Default files; `--dry-run` previews without filing. `lisa:verify` invokes monitor as `lisa:monitor <env> --report-only`, so the post-deploy check never files. Escalate anything not made into a ticket.
|
|
325
|
+
|
|
326
|
+
The `observability-audit` rule owns the profile detection, rubric, anomaly thresholds, ticket templates (gate-passing), fingerprint/idempotency contract, the cap, and the Verify report-only guard. Monitor **files only** — the `intake` / `tracker-build-intake` cron implements what it files.
|
|
322
327
|
|
|
323
328
|
## Tracker Entry Point (JIRA, GitHub Issues, or Linear)
|
|
324
329
|
|
|
@@ -104,6 +104,7 @@ This action is **terminal-only**:
|
|
|
104
104
|
- Intermediate env-keyed states such as `status:on-dev`, `status:on-stg`, `On Dev`, or `On Stg` remain open / unresolved / active. They are deployment waypoints, not terminal completion.
|
|
105
105
|
- A single-environment project whose `done` resolves to one value treats that value as terminal. In this repo, `production: main` means `status:done` / `Done` is terminal.
|
|
106
106
|
- A multi-environment project treats only the production / final environment's `done` value as terminal unless the project explicitly configures `done` as a single string. Do not close native work items at lower environments.
|
|
107
|
+
- Duplicate closeout is a narrow terminal exception: build intake may close a claimed item without a PR only when `ticket-triage` returns `DUPLICATE_ALREADY_FIXED` with a canonical item reference and empirical proof that the canonical fix is present on the relevant base branch. That closeout uses the provider's duplicate semantics (`Duplicate` resolution, duplicate/canceled state, or GitHub not-planned close with a duplicate link/comment), not the normal "completed build" reason. `BLOCKED`, ambiguous, duplicate-of-open, and other human-owned dispositions are not auto-closed.
|
|
107
108
|
- The native finalization must be idempotent. If the item is already closed / completed / resolved, report that and continue.
|
|
108
109
|
- If a provider exposes no native close / archive operation, or a project has not configured the native Done state, record a capability-aware no-op or setup error according to the vendor skill. Do not invent a state name.
|
|
109
110
|
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Observability Audit (load-bearing)
|
|
2
|
+
|
|
3
|
+
This rule is the single source of truth for the **audit + file** arm of the `lisa:monitor` skill. The `monitor` skill collects live signals (errors, logs, performance, health) via the stack `ops-specialist` exactly as before; this rule adds two things on top, both **repo-scoped**:
|
|
4
|
+
|
|
5
|
+
1. **Audit** — score the repo against an observability-completeness rubric for its detected type, so a frontend repo is never dinged for missing backend tracing.
|
|
6
|
+
2. **File** — turn both *anomalies* (a real bad live signal) and *gaps* (an in-scope observability dimension that isn't wired) into **build-ready leaf tickets** so the existing `intake` / `tracker-build-intake` cron picks them up and fixes them. `monitor` files only; it never fixes.
|
|
7
|
+
|
|
8
|
+
`monitor` is **manual** — there is no cron for it. It is run by a human against a named environment.
|
|
9
|
+
|
|
10
|
+
## Scope discipline (why this is repo-scoped)
|
|
11
|
+
|
|
12
|
+
`monitor` runs **inside one repo** and audits/files **only for that repo**. Two mechanisms enforce it:
|
|
13
|
+
|
|
14
|
+
- **Type-scoped rubric.** Only the dimensions in-scope for the detected repo type are audited (table below). A frontend-only repo never evaluates X-Ray tracing or DB-query analytics; a backend repo never evaluates Web Vitals or session replay.
|
|
15
|
+
- **`repo:<name>` stamping.** Every filed ticket is a single-repo leaf stamped `repo:<CURRENT_REPO>` (per `repo-scope-split`). Resolve `CURRENT_REPO` with the standard ladder from `config-resolution` ("Current-repo resolution"): config `repo` → `github.repo` → `basename` of the git remote. If it cannot be resolved, **report and skip filing** rather than filing un-scoped tickets.
|
|
16
|
+
|
|
17
|
+
## Repo-type detection (stack-agnostic)
|
|
18
|
+
|
|
19
|
+
`monitor` is a base skill that ships to every project, so detection must not assume a stack plugin is present. Detect the repo's observability **profile** by reading manifests and key files — never by assuming. Classify into one or more of `frontend`, `backend`, `infra`. A repo may be more than one (a Rails or Next.js app is `frontend`+`backend` = "fullstack"); audit the union of the matched profiles' in-scope dimensions.
|
|
20
|
+
|
|
21
|
+
| Profile | Positive signals (any) |
|
|
22
|
+
|---|---|
|
|
23
|
+
| `frontend` | `package.json` deps incl. `expo`, `react-native`, `next`, `react`, `vue`, `@angular/core`, `svelte`, `vite`; an `app.json` / `app/` route dir / `public/index.html`; a web/mobile build script |
|
|
24
|
+
| `backend` | `package.json` deps incl. `@nestjs/core`, `express`, `fastify`, `koa`, `@apollo/server`; a `serverless.yml` / Lambda handlers; a `Gemfile` with `rails`; a `Procfile`; an API/server entrypoint |
|
|
25
|
+
| `infra` | `aws-cdk-lib` + `cdk.json`; Terraform `*.tf`; Pulumi; a `serverless.yml` with no application code; a deploy-only repo |
|
|
26
|
+
|
|
27
|
+
When the Lisa stack overlay is present its mapping is a strong prior (`expo`→frontend, `nestjs`→backend, `cdk`→infra, `rails`→frontend+backend, `typescript`→infer from the signals above), but always confirm against the actual files — the overlay is a hint, the files are truth.
|
|
28
|
+
|
|
29
|
+
## The observability-completeness rubric
|
|
30
|
+
|
|
31
|
+
Each dimension is **in scope** (`●`) or **out of scope** (`–`) per profile, and carries a **tier**: `core` (a blind spot here is a real operational risk → file when missing) or `recommended` (valuable but optional → file only when `--all-gaps` is passed; otherwise report as a WARN row, do not ticket).
|
|
32
|
+
|
|
33
|
+
| Dimension | Tier | FE | BE | Infra | Detect via (presence ⇒ wired) |
|
|
34
|
+
|---|---|:--:|:--:|:--:|---|
|
|
35
|
+
| Error monitoring | core | ● | ● | – | `@sentry/*`, `.sentryclirc`, Sentry DSN in `.env*`; Bugsnag/Rollbar deps |
|
|
36
|
+
| Structured logging | core | ● | ● | ● | `pino`/`winston`/`bunyan`; Rails `lograge`; CloudWatch log groups exist |
|
|
37
|
+
| Distributed tracing | core | – | ● | ● | `aws-xray-sdk*`, OpenTelemetry deps/gems; X-Ray traces present |
|
|
38
|
+
| Metrics & alarms | core | – | ● | ● | CloudWatch custom metrics + `describe-alarms` returns alarms; Datadog/Prometheus |
|
|
39
|
+
| Health checks | core | ● | ● | – | a `/health`/`/up` endpoint; NestJS Terminus; uptime check config |
|
|
40
|
+
| RUM / Web Vitals | recommended | ● | – | – | Sentry performance/browser tracing, `web-vitals`, Firebase Performance |
|
|
41
|
+
| Product analytics | recommended | ● | – | – | `posthog-js`/`posthog-node`, Firebase Analytics, Amplitude, Segment |
|
|
42
|
+
| Session replay / frustration | recommended | ● | – | – | Jam, PostHog session replay, LogRocket, Sentry replay |
|
|
43
|
+
| DB / query analytics | recommended | – | ● | ● | slow-query logging, RDS/Aurora Performance Insights, query-timing middleware |
|
|
44
|
+
| Synthetic / smoke UAT | recommended | ● | ● | – | Playwright/Cypress e2e, k6/Artillery load scripts, synthetic canaries |
|
|
45
|
+
|
|
46
|
+
**Detection is read-then-probe, never assume.** For each in-scope dimension: read `package.json` deps + scripts (and `Gemfile`, `serverless.yml`, `docker-compose.yml`, `config/initializers/*`, `.env*`, `.sentryclirc`, `cdk.json`), then — only when credentials/tooling are already available — probe the live source (`command -v sentry-cli`, `aws sts get-caller-identity` before any `aws` call). Mirror the `ops-specialist` "Project Discovery" table where the stack overlay exists. **Absence of every signal for an in-scope dimension is the gap finding.** A dimension that is present but unreachable this run (e.g. PostHog wired but no API key available) is reported `PRESENT (unverified)`, **not** a gap.
|
|
47
|
+
|
|
48
|
+
### Tools Lisa does not wire
|
|
49
|
+
|
|
50
|
+
PostHog, Jam, and Firebase have **no Lisa MCP**. Detect them statically (deps/config) and pull their data only where a first-party API + credentials are already present in the environment (e.g. the PostHog API with a project key). Never invent credentials, and never treat "Lisa has no MCP for it" as "the repo lacks it" — judge by the repo's own deps/config.
|
|
51
|
+
|
|
52
|
+
## Live-signal anomalies (conservative thresholds)
|
|
53
|
+
|
|
54
|
+
Collect live signals via the stack `ops-specialist` when present (Expo/Rails), else via inline base probing (Sentry CLI/REST, `aws logs`, `aws cloudwatch`, `aws xray`, the Playwright MCP for client-side console/network). An observation becomes a **fileable anomaly** only when it clears the conservative bar — high-signal only, to keep the Ready queue clean. Defaults below (the keys live under `monitor.thresholds.*` in `config-resolution`; per-run nothing overrides them — tune in config):
|
|
55
|
+
|
|
56
|
+
| Signal | Fileable when |
|
|
57
|
+
|---|---|
|
|
58
|
+
| Sentry issue | `is:unresolved` **and** `level:error|fatal` **and** events in last 24h ≥ `sentryMinEvents24h` (default 10). Skip resolved/ignored/muted and below-floor noise. |
|
|
59
|
+
| Error-rate spike | error rate ≥ `errorRateSpikeMultiplier`× (default 2×) the prior-window baseline **and** above an absolute floor (not 1-of-2 requests). |
|
|
60
|
+
| Latency regression | p95 ≥ `p95LatencyMs` (default 1000ms) sustained, **or** p95 up ≥ 50% vs the prior window. |
|
|
61
|
+
| CloudWatch alarm | any alarm in `ALARM` state. |
|
|
62
|
+
| X-Ray fault rate | fault traces > `xrayFaultRatePct` (default 5%) of traces in the window. |
|
|
63
|
+
| Client-side (Playwright) | repeated console `error` or a 5xx network response on a smoke flow. |
|
|
64
|
+
|
|
65
|
+
Everything below the bar is reported (so the human sees it) but **not** ticketed. `--all-gaps` does not lower anomaly thresholds — it only widens *gap* tiers.
|
|
66
|
+
|
|
67
|
+
## Two finding types → build-ready leaf tickets
|
|
68
|
+
|
|
69
|
+
Both finding types are filed through the vendor-neutral `lisa:tracker-write` shim with `build_ready: true` (never a vendor write skill directly — that is what keeps the destination switchable). Both are **leaf** work units (`Bug` for anomalies, `Task`/`Improvement` for gaps) — never an Epic or container (gate S15). Each must pass the `tracker-validate` gates S1–S15, so each ticket is a real authored artifact, not a template dump.
|
|
70
|
+
|
|
71
|
+
### Required fields (so the gates pass)
|
|
72
|
+
|
|
73
|
+
- **Three-audience description** (S3): coding-assistant (technical: stack trace / Sentry link / occurrence count / the missing dimension and how to wire it), developer (where it surfaces, suspected cause/affected files, the fix skill to reach for), stakeholder (user/SLO impact).
|
|
74
|
+
- **Gherkin acceptance criteria** (S4).
|
|
75
|
+
- **Single repo** (S10): stamped `repo:<CURRENT_REPO>`; scope the description to this repo only.
|
|
76
|
+
- **Target Backend Environment** (S8) + **Validation Journey** carrying at least one unique kebab-case `[EVIDENCE: <name>]` marker (S11/S14) — both anomaly fixes and gap wiring are runtime changes, so both need an env and a journey that proves the fix. The bracketed `[EVIDENCE: <name>]` form is what the validator scans for; a bare `EVIDENCE:` line fails S14. Prefer two markers (a success and an error/edge case).
|
|
77
|
+
- **Relationship search before write** (S13) — doubles as the dedup guard (next section).
|
|
78
|
+
- **No parent/Epic required.** These are build-ready standalone leaves; S7's parent requirement is waived for a `build_ready: true` leaf (the leaf carve-out in `leaf-only-lifecycle` / `tracker-validate`). Do not fabricate an Epic parent.
|
|
79
|
+
- A **priority** ordered by tier and severity: `core` gap / high-event anomaly → higher; `recommended` gap → lower.
|
|
80
|
+
|
|
81
|
+
### Anomaly ticket (type: Bug)
|
|
82
|
+
|
|
83
|
+
Title: `[observability] <signal summary> (<source>)` — e.g. `[observability] Unhandled TypeError in CheckoutScreen (Sentry)`. The coding-assistant section carries the Sentry/CloudWatch/X-Ray link, fingerprint, first/last seen, and occurrence count. AC: *Given* the repro context, *When* the action runs, *Then* the source reports zero new events for the fingerprint. The fix-skill hint points at `root-cause-analysis` / `reproduce-bug`.
|
|
84
|
+
|
|
85
|
+
### Gap ticket (type: Task or Improvement)
|
|
86
|
+
|
|
87
|
+
Title: `[observability-gap] Add <dimension> (<profile>)` — e.g. `[observability-gap] Add distributed tracing (backend)`. The description states which dimension is missing, **why the audit needed it** (the blind spot it leaves), and how to wire it — chaining the existing fix skills where they apply (`parity-sentry-sdk-setup` for error monitoring; the nestjs `typeorm-patterns` skill's `observability-patterns` reference for X-Ray/CloudWatch DB-query tracing; OTel→X-Ray for tracing). AC: *Given* the app runs in `<env>`, *When* the relevant signal occurs, *Then* the newly-wired dimension captures it (dashboard/endpoint/trace shows data).
|
|
88
|
+
|
|
89
|
+
## Idempotency (do not re-file the same finding)
|
|
90
|
+
|
|
91
|
+
A manual re-run next week must not duplicate last week's tickets. Mirror the `repair-intake` marker discipline:
|
|
92
|
+
|
|
93
|
+
1. **Stable fingerprint per finding.**
|
|
94
|
+
- Anomaly: `sha1("<source>:<stable-signature>:<CURRENT_REPO>")` (12 hex chars). `stable-signature` is the Sentry issue short-id (or culprit), the CloudWatch alarm name, or `errorType@location` — something that survives between runs, **never** the human title or occurrence count.
|
|
95
|
+
- Gap: the literal `gap:<dimension>:<CURRENT_REPO>` (a dimension is missing-or-not; no hash needed).
|
|
96
|
+
2. **Sentinel in the body.** Embed `<!-- lisa-monitor-finding: <fingerprint> -->` in every filed ticket.
|
|
97
|
+
3. **Search before create** (this IS gate S13). Before filing, search the tracker for the fingerprint string. The search **MUST include closed/resolved tickets** (`gh issue list --search <fp> --state all` for GitHub; JQL with no status filter for JIRA; all states for Linear) — otherwise a just-closed match is invisible and the backoff below can't fire. If an **open** ticket carries the fingerprint → skip (optionally link). If a ticket carrying it was closed **within the recently-resolved backoff window** (`monitor.backoffHours`, default **24h** — matching the 24h Sentry event window; this is **not** the 2h `intake.repair.staleAfterHours`) → skip, to avoid re-filing a just-fixed regression before its signal has drained. Only file when no live or recently-resolved match exists.
|
|
98
|
+
|
|
99
|
+
## The cap
|
|
100
|
+
|
|
101
|
+
File **at most `max_candidates` tickets per run** (default **20**; config `monitor.maxCandidates`; per-run `max_candidates=<n>` always wins). Rank candidates before applying the cap — `core` gaps and highest-occurrence anomalies first — so the cap drops the least-important findings, never the most. When the cap truncates, **list every dropped finding** in the report (title + fingerprint, not just a count) — silent truncation reads as "all clear" when it isn't, and a high-signal anomaly that fell just below the cap must still be visible to the human.
|
|
102
|
+
|
|
103
|
+
## Filing modes and the Verify guard
|
|
104
|
+
|
|
105
|
+
- **Default (standalone `monitor <env>`): files.** A plain manual run audits, reports, dedupes, and files up to the cap.
|
|
106
|
+
- **`--dry-run`:** does everything except call `tracker-write` — prints exactly which tickets *would* be filed (title, type, fingerprint, dedup verdict) so the human can preview.
|
|
107
|
+
- **`--report-only`:** produces the health/audit summary only — no filing and no would-file analysis. This is the mode Verify uses (below).
|
|
108
|
+
- **Invoked as `lisa:verify`'s post-deploy step: never files — enforced mechanically, not inferred.** `lisa:verify` step 6 invokes monitor as `lisa:monitor <env> --report-only`; monitor must never file when `--report-only` (or `--dry-run`) is set. This is load-bearing **today** — Verify already routes its remote verification through the `monitor` skill, so without the passed flag the new file-by-default behavior would create tickets during every verify run. As a belt-and-suspenders default, if monitor is invoked via the Skill tool from within a Verify flow and no filing flag was passed, treat it as `--report-only` rather than filing.
|
|
109
|
+
|
|
110
|
+
## Output
|
|
111
|
+
|
|
112
|
+
A single report: the health/anomaly summary (existing monitor behavior) + an audit table (each in-scope dimension with `OK` / `WARN` / `MISSING` / `PRESENT (unverified)`) + a filing summary (tickets filed with their refs and fingerprints, tickets skipped as duplicates, and the dropped count if the cap truncated). In `--dry-run`, the filing summary lists would-file tickets instead.
|
|
113
|
+
|
|
114
|
+
## Rules
|
|
115
|
+
|
|
116
|
+
- File only — never fix. The `intake` / `tracker-build-intake` cron implements what `monitor` files.
|
|
117
|
+
- Always through `tracker-write` with `build_ready: true`; never a vendor write skill directly.
|
|
118
|
+
- Conservative by default — high-signal anomalies and `core` missing dimensions only. `--all-gaps` widens gap tiers; nothing lowers the anomaly bar.
|
|
119
|
+
- Repo-scoped always — type-scoped rubric + `repo:<CURRENT_REPO>` single-repo leaves. Cannot resolve the repo → report, do not file.
|
|
120
|
+
- Idempotent always — fingerprint sentinel + search-before-create; a re-run never duplicates a live or just-resolved finding.
|
|
121
|
+
- Never file without a real, gate-passing description and Validation Journey. A finding that cannot be made into a credible ticket is reported, not filed.
|
|
122
|
+
- Read config with `jq` (local-overrides-global) per `config-resolution`; never hand-parse JSON. Never run an `aws`/`sentry-cli` probe without first confirming credentials.
|