session-orchestrator 3.17.0 → 3.19.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor/rules/030-wave-execution.mdc +17 -1
- package/CHANGELOG.md +105 -412
- package/README.md +12 -9
- package/SECURITY.md +190 -27
- package/agents/AGENTS.md +20 -3
- package/agents/code-implementer.md +6 -6
- package/agents/db-specialist.md +1 -1
- package/agents/qa-strategist.md +31 -6
- package/agents/schemas/qa-strategist.schema.json +27 -0
- package/agents/schemas/test-writer.schema.json +60 -2
- package/agents/security-reviewer.md +1 -1
- package/agents/session-reviewer.md +1 -1
- package/agents/test-writer.md +29 -10
- package/agents/ui-developer.md +1 -1
- package/commands/contract-version-bump.md +28 -0
- package/commands/portfolio.md +1 -1
- package/docs/USER-GUIDE.md +8 -3
- package/docs/ci-setup.md +121 -7
- package/docs/codex-setup.md +1 -1
- package/docs/components.md +6 -6
- package/docs/cursor-setup.md +22 -9
- package/docs/events-schema.md +5 -1
- package/docs/instruction-delivery.md +444 -0
- package/docs/rule-authoring.md +58 -9
- package/docs/session-config-reference.md +244 -9
- package/docs/session-config-template.md +39 -3
- package/hooks/_lib/guard-source-loader.mjs +467 -0
- package/hooks/_lib/lock-bootstrap.mjs +21 -0
- package/hooks/_lib/vcs-create-matcher.mjs +119 -0
- package/hooks/config-protection.mjs +0 -0
- package/hooks/enforce-commands.mjs +10 -2
- package/hooks/hooks-codex.json +1 -1
- package/hooks/hooks-cursor.json +11 -2
- package/hooks/hooks-pi.json +10 -0
- package/hooks/hooks.json +21 -1
- package/hooks/on-session-end.mjs +178 -18
- package/hooks/on-session-start.mjs +23 -0
- package/hooks/post-bash-write-verify.mjs +977 -0
- package/hooks/post-subagent-discovery-validator.mjs +256 -41
- package/hooks/pre-bash-destructive-guard.mjs +525 -160
- package/hooks/pre-bash-issue-budget.mjs +167 -0
- package/hooks/pre-bash-sessions-ledger-guard.mjs +627 -0
- package/hooks/pre-bash-templates-first.mjs +96 -63
- package/hooks/subagent-telemetry.mjs +527 -37
- package/package.json +5 -2
- package/pi/prompts/contract-version-bump.md +12 -0
- package/rules/README.md +32 -0
- package/scripts/archive-closed-prds.mjs +12 -22
- package/scripts/autopilot-multi.mjs +103 -20
- package/scripts/backfill-abandoned-sessions.mjs +160 -4
- package/scripts/check-doc-consistency.sh +17 -1
- package/scripts/eval-session.mjs +50 -9
- package/scripts/fleet-instruction-scan.mjs +141 -0
- package/scripts/lib/autopilot/mr-draft.mjs +31 -1
- package/scripts/lib/autopilot/worktree-pipeline.mjs +113 -5
- package/scripts/lib/backlog-scan.mjs +39 -6
- package/scripts/lib/blocked-commands-policy.mjs +340 -0
- package/scripts/lib/ci-status-banner.mjs +75 -12
- package/scripts/lib/claude-md-budget-lint.mjs +283 -34
- package/scripts/lib/command-blocker.mjs +1013 -58
- package/scripts/lib/config/config-protection.mjs +2 -1
- package/scripts/lib/config/drift-check.mjs +9 -1
- package/scripts/lib/config/gitlab-portfolio.mjs +1 -1
- package/scripts/lib/config/issue-budget.mjs +123 -0
- package/scripts/lib/config/reconcile.mjs +21 -0
- package/scripts/lib/config/section-extractor.mjs +121 -1
- package/scripts/lib/config-schema.mjs +23 -3
- package/scripts/lib/config.mjs +17 -0
- package/scripts/lib/convergence-monitor.mjs +49 -3
- package/scripts/lib/description-surface.mjs +535 -0
- package/scripts/lib/dispatcher/enumerate.mjs +26 -40
- package/scripts/lib/ecosystem-wizard/config-writer.mjs +26 -24
- package/scripts/lib/ecosystem-wizard/wizard-prompt.mjs +1 -1
- package/scripts/lib/eval/engine.mjs +47 -5
- package/scripts/lib/events.mjs +59 -7
- package/scripts/lib/gates/gate-full.mjs +15 -3
- package/scripts/lib/gates/gate-helpers.mjs +132 -6
- package/scripts/lib/gitlab-ops/stale-mr-sweep.mjs +28 -8
- package/scripts/lib/gitlab-portfolio/aggregator.mjs +8 -2
- package/scripts/lib/gitlab-portfolio/cli.mjs +1 -1
- package/scripts/lib/handover-gate.mjs +7 -3
- package/scripts/lib/harness-audit/categories/category4.mjs +9 -3
- package/scripts/lib/instruction-budget-guard.mjs +402 -51
- package/scripts/lib/io.mjs +345 -10
- package/scripts/lib/issue-budget.mjs +269 -0
- package/scripts/lib/issue-close-strip-labels.mjs +39 -9
- package/scripts/lib/label-scope.mjs +47 -0
- package/scripts/lib/learnings/schema.mjs +43 -3
- package/scripts/lib/lock-reaper.mjs +1 -2
- package/scripts/lib/memory-proposals/schema.mjs +36 -1
- package/scripts/lib/peer-discovery.mjs +645 -0
- package/scripts/lib/pi-hook-bridge.mjs +146 -17
- package/scripts/lib/product-repo-detect.mjs +9 -8
- package/scripts/lib/project-hygiene.mjs +432 -0
- package/scripts/lib/quality-gate.mjs +167 -0
- package/scripts/lib/recommendations-v0.mjs +1 -1
- package/scripts/lib/reconcile/eligibility.mjs +1 -1
- package/scripts/lib/reconcile/emitter.mjs +23 -4
- package/scripts/lib/reconcile/engine.mjs +147 -39
- package/scripts/lib/reconcile/idempotency.mjs +114 -14
- package/scripts/lib/reconcile-nudge-banner.mjs +65 -9
- package/scripts/lib/resource-probe/evaluate.mjs +70 -4
- package/scripts/lib/resource-probe.mjs +19 -0
- package/scripts/lib/rule-loader.mjs +6 -0
- package/scripts/lib/scope-baseline.mjs +564 -0
- package/scripts/lib/scope-gate.mjs +399 -98
- package/scripts/lib/session-close-backfill.mjs +61 -6
- package/scripts/lib/session-end/phase-skip.mjs +1 -0
- package/scripts/lib/session-id.mjs +221 -41
- package/scripts/lib/session-lock.mjs +304 -6
- package/scripts/lib/session-schema/constants.mjs +22 -3
- package/scripts/lib/session-schema/validator.mjs +16 -0
- package/scripts/lib/sessions-integrity-banner.mjs +294 -0
- package/scripts/lib/sessions-staleness-banner.mjs +121 -12
- package/scripts/lib/skill-evolution/idempotency.mjs +135 -16
- package/scripts/lib/skill-evolution/mr-opener.mjs +9 -1
- package/scripts/lib/spiral-carryover.mjs +142 -30
- package/scripts/lib/state-md/mission-status.mjs +53 -3
- package/scripts/lib/subagents-schema.mjs +43 -9
- package/scripts/lib/test-runner/issue-reconcile.mjs +53 -13
- package/scripts/lib/tests-src-ratio.mjs +484 -0
- package/scripts/lib/validate/check-agents.mjs +56 -0
- package/scripts/lib/validate/check-hooks-symmetry.mjs +244 -10
- package/scripts/lib/validate/check-rules.mjs +217 -35
- package/scripts/lib/validate/check-test-value-bans.mjs +782 -0
- package/scripts/lib/validate/check-unicode-safety.mjs +1 -0
- package/scripts/lib/validate-vendored-rules.mjs +10 -2
- package/scripts/lib/vault-archive.mjs +17 -2
- package/scripts/lib/vault-backfill/glab.mjs +8 -0
- package/scripts/lib/vault-mirror/process.mjs +30 -0
- package/scripts/lib/vault-mirror/render-sessions.mjs +293 -36
- package/scripts/lib/vcs-repo-spec.mjs +362 -0
- package/scripts/lib/wave-resource-gate.mjs +115 -11
- package/scripts/lib/worktree/listing.mjs +44 -7
- package/scripts/mcp-server.sh +17 -3
- package/scripts/measure-context-overhead.sh +151 -0
- package/scripts/memory-propose.mjs +72 -9
- package/scripts/print-applicable-rules.mjs +51 -12
- package/scripts/release.mjs +534 -0
- package/scripts/run-quality-gate.mjs +123 -5
- package/scripts/validate-wave-scope.mjs +182 -17
- package/scripts/vault-integration-watcher.mjs +32 -10
- package/skills/_shared/config-reading.md +2 -2
- package/skills/bootstrap/fast-template.md +1 -1
- package/skills/claude-md-drift-check/checker.mjs +145 -28
- package/skills/contract-version-bump/SKILL.md +219 -0
- package/skills/discovery/SKILL.md +4 -4
- package/skills/discovery/issue-templates.md +11 -11
- package/skills/discovery/probes-audit.md +1 -1
- package/skills/discovery/probes-feature.md +1 -1
- package/skills/discovery/probes-session.md +26 -5
- package/skills/ecosystem-health/SKILL.md +1 -1
- package/skills/ecosystem-health/wizard.md +4 -4
- package/skills/evolve/SKILL.md +1 -0
- package/skills/gitlab-ops/SKILL.md +20 -12
- package/skills/gitlab-portfolio/SKILL.md +2 -2
- package/skills/hook-development/SKILL.md +1 -1
- package/skills/mode-selector/SKILL.md +1 -1
- package/skills/npm-publish/SKILL.md +17 -1
- package/skills/plan/SKILL.md +5 -5
- package/skills/plan/mode-feature.md +4 -4
- package/skills/plan/mode-new.md +10 -10
- package/skills/plan/mode-retro.md +1 -1
- package/skills/quality-gates/SKILL.md +1 -1
- package/skills/reconcile/SKILL.md +21 -4
- package/skills/session-end/SKILL.md +34 -13
- package/skills/session-end/discovery-scan.md +4 -2
- package/skills/session-end/drift-operations.md +4 -4
- package/skills/session-end/metrics-collection.md +13 -0
- package/skills/session-end/phase-3-2-docs-verification.md +1 -1
- package/skills/session-end/phase-3-6-tail.md +2 -1
- package/skills/session-end/plan-verification.md +5 -2
- package/skills/session-end/vault-operations.md +1 -1
- package/skills/session-end/verification-checklist.md +1 -1
- package/skills/session-plan/SKILL.md +6 -2
- package/skills/session-plan/wave-template.md +2 -0
- package/skills/session-start/SKILL.md +73 -7
- package/skills/session-start/phase-4-5-resource-health.md +15 -2
- package/skills/test-runner/SKILL.md +2 -2
- package/skills/vault-sync/validator.mjs +108 -7
- package/skills/wave-executor/SKILL.md +5 -2
- package/skills/wave-executor/circuit-breaker.md +2 -0
- package/skills/wave-executor/wave-loop.md +163 -10
- package/templates/_shared/loop.md +4 -4
|
@@ -91,7 +91,7 @@ gh issue list --limit 100 --json number,title,labels,updatedAt,assignees --jq '.
|
|
|
91
91
|
# Flag:
|
|
92
92
|
# - Issues with no activity in stale-issue-days (default: 30 days)
|
|
93
93
|
# - Issues assigned but with no associated branch
|
|
94
|
-
# - Issues labeled priority
|
|
94
|
+
# - Issues labeled priority::high or priority::critical that are stale
|
|
95
95
|
|
|
96
96
|
# Check for associated branches:
|
|
97
97
|
git branch -r | grep -i "<issue_number>"
|
|
@@ -109,7 +109,7 @@ Has Branch: true | false
|
|
|
109
109
|
Priority: <priority label or NONE>
|
|
110
110
|
```
|
|
111
111
|
|
|
112
|
-
**Default Severity:** Low. Medium if `priority
|
|
112
|
+
**Default Severity:** Low. Medium if `priority::high` or `priority::critical` is stale.
|
|
113
113
|
|
|
114
114
|
---
|
|
115
115
|
|
|
@@ -231,14 +231,35 @@ Actual: <what was found or NOT found>
|
|
|
231
231
|
|
|
232
232
|
5. Token efficiency — CLAUDE.md size:
|
|
233
233
|
```bash
|
|
234
|
-
#
|
|
235
|
-
wc -l
|
|
234
|
+
# Delegate the threshold — do NOT re-implement it here. This probe used to
|
|
235
|
+
# carry its own numbers (`wc -l` > 150 warn / > 250 high); both the unit and
|
|
236
|
+
# the value were wrong. The ceiling is `DEFAULT_MAX_LINES = 80` and it applies
|
|
237
|
+
# to NON-EXEMPT effective lines: the runtime-critical `## Session Config` block
|
|
238
|
+
# is machine-parsed configuration, not trimmable prose, so a raw `wc -l` gate
|
|
239
|
+
# flags a compliant lean-root file (this plugin's own CLAUDE.md: 209 raw lines,
|
|
240
|
+
# 61 non-exempt — a `wc -l` rule fires, the lint passes).
|
|
241
|
+
REPO_ROOT="$(git rev-parse --show-toplevel)"
|
|
242
|
+
node "${PLUGIN_ROOT}/scripts/lib/claude-md-budget-lint.mjs" \
|
|
243
|
+
--repo-root "$REPO_ROOT" --mode warn --json
|
|
244
|
+
# → {"status":"ok"|"invalid","file":…,"lineCount":…,"exemptLines":…,
|
|
245
|
+
# "effectiveLineCount":…,"maxLineCharsSeen":…,"hasProvenance":…,
|
|
246
|
+
# "violations":[{"rule":"max-lines"|"max-line-chars"|…,"message":…}]}
|
|
247
|
+
# Flag ONLY on a violations[] entry — never on lineCount vs a local number.
|
|
248
|
+
# `--mode warn` keeps the exit code 0, so read the JSON, not `$?`.
|
|
249
|
+
|
|
250
|
+
# Ceiling value, when a finding needs to quote it (e.g. a 2x high tier):
|
|
251
|
+
node --input-type=module -e "
|
|
252
|
+
import { DEFAULT_MAX_LINES } from '${PLUGIN_ROOT}/scripts/lib/claude-md-budget-lint.mjs';
|
|
253
|
+
process.stdout.write(String(DEFAULT_MAX_LINES));
|
|
254
|
+
"
|
|
236
255
|
|
|
237
|
-
#
|
|
256
|
+
# Heuristics the lint does NOT measure — still eyeball these:
|
|
238
257
|
# Identify sections > 30 lines that could move to <state-dir>/rules/ or <state-dir>/docs/
|
|
239
258
|
# Check for inline code blocks > 10 lines (should be in separate files)
|
|
240
259
|
```
|
|
241
260
|
|
|
261
|
+
**Dependencies (probe 5):** requires `${PLUGIN_ROOT}/scripts/lib/claude-md-budget-lint.mjs` (#722 Epic A). Degrades gracefully when the helper is absent (pre-#722 plugin install) — skip the size finding with a note, do not fall back to a hand-rolled `wc -l` threshold, which is the drift this delegation removes.
|
|
262
|
+
|
|
242
263
|
6. Token efficiency — .claudeignore coverage:
|
|
243
264
|
```bash
|
|
244
265
|
# Check if .claudeignore exists
|
|
@@ -91,7 +91,7 @@ and skip this section.
|
|
|
91
91
|
Using the detected VCS CLI (per gitlab-ops "Common CLI Commands" and "Dynamic Project Resolution" sections):
|
|
92
92
|
|
|
93
93
|
1. Resolve the project ID or owner/repo slug for each cross-repo
|
|
94
|
-
2. Query open issues with `priority
|
|
94
|
+
2. Query open issues with `priority::critical` or `priority::high` labels (limit 5 per repo)
|
|
95
95
|
3. Collect results across all configured repos
|
|
96
96
|
|
|
97
97
|
## CI Pipeline Status
|
|
@@ -78,8 +78,8 @@ CI pipeline identifiers (format "id" or "id:label", comma-separated, blank to sk
|
|
|
78
78
|
### Prompt 2c — Critical Issue Labels
|
|
79
79
|
|
|
80
80
|
```
|
|
81
|
-
Critical issue labels (comma-separated, e.g. "priority
|
|
82
|
-
> priority
|
|
81
|
+
Critical issue labels (comma-separated, e.g. "priority::critical,severity:blocker", blank to skip):
|
|
82
|
+
> priority::critical, severity:blocker
|
|
83
83
|
```
|
|
84
84
|
|
|
85
85
|
- Raw label strings as they appear in the VCS issue tracker.
|
|
@@ -121,7 +121,7 @@ ecosystem-health:
|
|
|
121
121
|
pipelines:
|
|
122
122
|
- id: main
|
|
123
123
|
- id: deploy-production # Deploy
|
|
124
|
-
critical-issue-labels: ["priority
|
|
124
|
+
critical-issue-labels: ["priority::critical", "severity:blocker"]
|
|
125
125
|
```
|
|
126
126
|
|
|
127
127
|
**Idempotency:** If an `ecosystem-health:` key already exists in Session Config,
|
|
@@ -141,7 +141,7 @@ exits 0. Re-run to edit: remove the existing block first, then re-run.
|
|
|
141
141
|
{ "id": "main" },
|
|
142
142
|
{ "id": "deploy-production", "label": "Deploy" }
|
|
143
143
|
],
|
|
144
|
-
"criticalIssueLabels": ["priority
|
|
144
|
+
"criticalIssueLabels": ["priority::critical", "severity:blocker"]
|
|
145
145
|
}
|
|
146
146
|
```
|
|
147
147
|
|
package/skills/evolve/SKILL.md
CHANGED
|
@@ -261,6 +261,7 @@ For confirmed learnings, use atomic rewrite strategy:
|
|
|
261
261
|
- `source_session`: **non-empty kebab-slug string** identifying the session from which the pattern was extracted (e.g. `main-2026-04-27-1942`). MUST be a string — never an object, array, number, or null. If multiple sessions contributed, use the earliest. If unknown, use `"unknown"` (the string). **Never** pass `String(<object>)` — that yields `"[object Object]"` and breaks the YAML mirror downstream (#307). Optional pre-write validation: `jq -e 'select(.source_session | type == "string" and length > 2)'`.
|
|
262
262
|
- `created_at`: current ISO 8601 date
|
|
263
263
|
- `expires_at`: preserve the candidate's derived expiry when supplied; otherwise derive from `LEARNING_TTL_DAYS[type]` via `deriveExpiresAt()` (falling back to the schema default) rather than hard-coding a 30-day horizon
|
|
264
|
+
- `file_paths` (optional): repo-relative path(s) scoping the learning to specific files/directories. Required for a learning to ever become `/reconcile`-eligible (issue #900; see `docs/rule-authoring.md` § "Learning Type-Taxonomy, TTL & Provenance Standard"). For a `fragile-file` candidate, `file_paths: [subject]` is mechanically derivable — `subject` already IS the file path.
|
|
264
265
|
5. **Verify write**: Read back the first line of the written file to confirm valid JSON. If read-back fails or is not valid JSON, report error to user.
|
|
265
266
|
6. **Prune:** remove entries where `expires_at` < current date OR `confidence` <= 0.0
|
|
266
267
|
7. **Consolidate duplicates (NULL-SUBJECT SAFE):** if same `type` + `subject` appears more than once
|
|
@@ -6,7 +6,7 @@ model: haiku
|
|
|
6
6
|
model-preference: sonnet
|
|
7
7
|
model-preference-codex: gpt-5.4-mini
|
|
8
8
|
model-preference-cursor: claude-sonnet-4-6
|
|
9
|
-
description: Use this skill when performing VCS operations on GitLab or GitHub repositories — creating, updating, or closing issues and MRs, applying label taxonomy, running `glab`/`gh` CLI commands, or resolving project IDs dynamically. Acts as the single source of truth for CLI command syntax and label conventions; consuming skills reference this rather than duplicating logic. Triggers: "create a GitLab issue", "list open MRs", "apply priority label", "how do I resolve the project ID", "what's the carryover issue template". <example>Context: session-end needs to file a carryover issue for an incomplete task. user: "/close" assistant: "Creating carryover issue via glab with the Carryover Template from gitlab-ops — labels: carryover, priority
|
|
9
|
+
description: Use this skill when performing VCS operations on GitLab or GitHub repositories — creating, updating, or closing issues and MRs, applying label taxonomy, running `glab`/`gh` CLI commands, or resolving project IDs dynamically. Acts as the single source of truth for CLI command syntax and label conventions; consuming skills reference this rather than duplicating logic. Triggers: "create a GitLab issue", "list open MRs", "apply priority label", "how do I resolve the project ID", "what's the carryover issue template". <example>Context: session-end needs to file a carryover issue for an incomplete task. user: "/close" assistant: "Creating carryover issue via glab with the Carryover Template from gitlab-ops — labels: carryover, priority::high."</example>
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# VCS Operations Reference
|
|
@@ -99,13 +99,21 @@ done
|
|
|
99
99
|
|
|
100
100
|
## Label Taxonomy
|
|
101
101
|
|
|
102
|
-
**Taxonomy convention
|
|
102
|
+
**Taxonomy convention — `priority` REVERSED to scoped `::` (supersedes #727 for this one axis).**
|
|
103
|
+
|
|
104
|
+
- **`priority::<level>` is canonical.** #727's stated rationale was that "this repo mirrors to GitHub, which has no scoped-label semantics … while a migration would break every existing label reference and issue." Both halves were checked on 2026-07-25 and neither holds:
|
|
105
|
+
- **Issues are not mirrored at all.** `aiat-poc-infra/docs/github-mirror-runbook.md:1,5` describes a git **push-mirror** with GitHub as "read-only downstream"; `docs/gitlab-team-org-2026-06-21.md:45` confirms there is no two-way GitLab issue sync. Nothing crosses the boundary that a label rename could break.
|
|
106
|
+
- **GitHub already uses the scoped form.** `gh api "repos/AIAT-AIandBusinessgrowth/aiat-barrierefrei-engine/labels"` returns `priority::high`, `priority::low`, `priority::med`, `priority::medium` across 77 open issues, and **zero** `priority:high`. Same pattern on `aiat-doc-vlm`. GitHub treats `::` as an ordinary string; it merely does not enforce mutual exclusion.
|
|
107
|
+
- Volume agrees independently: **416 `priority::` against 249 `priority:` and 7 bare** at the time of the decision. Chasing the minority spelling would mean re-labelling the majority.
|
|
108
|
+
Producers were migrated FIRST (this change); the label-data migration follows separately, because migrating data before producers means the divergence returns within a day.
|
|
109
|
+
- **`area:` / `type:` / `status:` / `from:` stay SINGLE-COLON** — but NOT on #727's rationale, which is disproven above. They stay because nothing measured argues for flipping them, and because each axis is its own migration cost. Flipping them is a separate decision and is explicitly NOT made here. Note that `status` in particular is the worst-disciplined axis on the instance (354 assignments, only 48 percent scoped, 5 genuine value conflicts), so any future flip there needs a conflict-resolution pass first.
|
|
110
|
+
- **Readers accept both spellings.** Every consumer that MATCHES a label compares through `scripts/lib/label-scope.mjs` `normalizeLabel()`, which collapses `::` to `:` — so issues still carrying `priority:high` keep being counted until the data migration lands. Only WRITES are canonical.
|
|
103
111
|
|
|
104
112
|
### Priority Labels
|
|
105
|
-
- `priority
|
|
106
|
-
- `priority
|
|
107
|
-
- `priority
|
|
108
|
-
- `priority
|
|
113
|
+
- `priority::critical` — blocking production or users
|
|
114
|
+
- `priority::high` — important, schedule this sprint
|
|
115
|
+
- `priority::medium` — plan for next sprint
|
|
116
|
+
- `priority::low` — backlog, nice-to-have
|
|
109
117
|
|
|
110
118
|
### Status Labels
|
|
111
119
|
- `status:ready` — defined, ready to pick up
|
|
@@ -151,11 +159,11 @@ GitHub has no native issue-blocking relation at all — the body-ordering-note f
|
|
|
151
159
|
# Issues
|
|
152
160
|
glab issue list --per-page 50 # All open issues
|
|
153
161
|
glab issue list --label "status:ready" --per-page 10 # Ready to work on
|
|
154
|
-
glab issue list --label "priority
|
|
162
|
+
glab issue list --label "priority::high" --per-page 10 # High priority
|
|
155
163
|
glab issue list --closed --per-page 10 # Recently closed
|
|
156
164
|
glab issue view <IID> # View issue details
|
|
157
165
|
glab issue view <IID> --comments # With comments
|
|
158
|
-
glab issue create --title "title" --label "priority
|
|
166
|
+
glab issue create --title "title" --label "priority::high,status:ready"
|
|
159
167
|
glab issue update <IID> --label "status:in-progress" # WARNING: --label REPLACES the full set — see caveat below
|
|
160
168
|
glab issue close <IID> # then VERIFY: glab issue view <IID> must show state=closed
|
|
161
169
|
glab issue note <IID> -m "Comment text" # Add comment
|
|
@@ -188,11 +196,11 @@ glab api "projects/$(glab repo view --output json | python3 -c "import json,sys;
|
|
|
188
196
|
# Issues
|
|
189
197
|
gh issue list --limit 50 # All open issues
|
|
190
198
|
gh issue list --label "status:ready" --limit 10 # Ready to work on
|
|
191
|
-
gh issue list --label "priority
|
|
199
|
+
gh issue list --label "priority::high" --limit 10 # High priority
|
|
192
200
|
gh issue list --state closed --limit 10 # Recently closed
|
|
193
201
|
gh issue view <NUMBER> # View issue details
|
|
194
202
|
gh issue view <NUMBER> --comments # With comments
|
|
195
|
-
gh issue create --title "title" --label "priority
|
|
203
|
+
gh issue create --title "title" --label "priority::high,status:ready"
|
|
196
204
|
gh issue edit <NUMBER> --add-label "status:in-progress"
|
|
197
205
|
gh issue close <NUMBER>
|
|
198
206
|
gh issue comment <NUMBER> --body "Comment text" # Add comment
|
|
@@ -272,7 +280,7 @@ Relates to #ORIGINAL_IID
|
|
|
272
280
|
## [Discovery] <finding title>
|
|
273
281
|
|
|
274
282
|
**Probe:** <probe_name>
|
|
275
|
-
**Severity:** <priority
|
|
283
|
+
**Severity:** <priority::critical|high|medium|low>
|
|
276
284
|
**Category:** <code|infra|ui|arch|session|audit|vault|feature>
|
|
277
285
|
|
|
278
286
|
### Finding
|
|
@@ -302,7 +310,7 @@ Relates to #ORIGINAL_IID
|
|
|
302
310
|
- [ ] Quality gates pass after fix
|
|
303
311
|
```
|
|
304
312
|
|
|
305
|
-
Labels: `type:discovery`, `priority
|
|
313
|
+
Labels: `type:discovery`, `priority::<level>`, `area:<inferred>`, `status:ready`
|
|
306
314
|
|
|
307
315
|
## Template-First Enforcement (PSA-005 + #519)
|
|
308
316
|
|
|
@@ -93,7 +93,7 @@ gitlab-portfolio:
|
|
|
93
93
|
enabled: true
|
|
94
94
|
mode: warn # warn | strict | off
|
|
95
95
|
stale-days: 30
|
|
96
|
-
critical-labels: ["priority
|
|
96
|
+
critical-labels: ["priority::critical", "priority::high"]
|
|
97
97
|
```
|
|
98
98
|
|
|
99
99
|
| Field | Default | Meaning |
|
|
@@ -101,7 +101,7 @@ gitlab-portfolio:
|
|
|
101
101
|
| `enabled` | `false` | Master switch. |
|
|
102
102
|
| `mode` | `warn` | `warn` / `strict` / `off` — failure handling; `off` ≡ disabled. |
|
|
103
103
|
| `stale-days` | `30` | Issues older than N days are flagged stale. |
|
|
104
|
-
| `critical-labels` | `["priority
|
|
104
|
+
| `critical-labels` | `["priority::critical","priority::high"]` | Label substrings that classify an issue as critical (case-insensitive). |
|
|
105
105
|
|
|
106
106
|
### Security
|
|
107
107
|
|
|
@@ -292,7 +292,7 @@ enabled=$(jq -r '.strictMode // false' "$CONFIG_FILE" 2>/dev/null)
|
|
|
292
292
|
|
|
293
293
|
## Our in-house examples (read these, not the upstream `examples/`)
|
|
294
294
|
|
|
295
|
-
- `hooks/pre-bash-destructive-guard.mjs` — policy-driven command blocker,
|
|
295
|
+
- `hooks/pre-bash-destructive-guard.mjs` — policy-driven command blocker, 14 rules in `.orchestrator/policy/blocked-commands.json`
|
|
296
296
|
- `hooks/enforce-scope.mjs` — wave-scope boundary enforcement using `.orchestrator/wave-scope.json`
|
|
297
297
|
- `hooks/on-session-start.mjs` — banner + session init
|
|
298
298
|
- `hooks/post-edit-validate.mjs` — validates edits after the fact
|
|
@@ -216,7 +216,7 @@ Missing signal fields contribute 0 to the score — no NaN propagation.
|
|
|
216
216
|
## Open Questions (for Phase B-1 follow-up)
|
|
217
217
|
|
|
218
218
|
- Learnings freshness window — default 30d? Configurable per-type or a single global TTL?
|
|
219
|
-
- Backlog priority weighting — rule-based (`priority
|
|
219
|
+
- Backlog priority weighting — rule-based (`priority::critical = +0.2` confidence bonus) vs.
|
|
220
220
|
learned from historical completion rates?
|
|
221
221
|
- Alternative-generation algorithm — top-N non-selected modes scored by partial signal match, or
|
|
222
222
|
fixed set derived from v0 heuristic branches?
|
|
@@ -29,7 +29,23 @@ Create at https://www.npmjs.com/settings/<user>/tokens → Generate New Token
|
|
|
29
29
|
|
|
30
30
|
**Never** put the token in the tracked `.npmrc` (it holds `ignore-scripts=true` per SEC-020 and is committed), never persist it into `~/.npmrc`, never echo it into logs.
|
|
31
31
|
|
|
32
|
-
##
|
|
32
|
+
## Canonical path: `scripts/release.mjs` (Release als ein Dispatch, #978)
|
|
33
|
+
|
|
34
|
+
Since v3.19.0 the release is ONE dispatch — the script mechanizes every step below plus the
|
|
35
|
+
version-surface sync this skill previously left to operator memory (the gap that let v3.18.0
|
|
36
|
+
ship tagged but unpublished):
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
node scripts/release.mjs --set-version X.Y.Z # rewrite all 12 version literals (10 files) + codex cachebuster + lock sync
|
|
40
|
+
# … author CHANGELOG entry + README highlights (enforced by --check) …
|
|
41
|
+
node scripts/release.mjs --check # preflight: surfaces, CHANGELOG, tag/registry collision, CI green, leakage gate
|
|
42
|
+
node scripts/release.mjs --publish # token publish → registry verify → tag AFTER publish → push origin+github
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The tag is created only AFTER a registry-verified publish — never before. The manual flow
|
|
46
|
+
below remains as the fallback and as documentation of what the script does.
|
|
47
|
+
|
|
48
|
+
## Publish flow (manual fallback)
|
|
33
49
|
|
|
34
50
|
```bash
|
|
35
51
|
# 1. Pre-flight (first publish: expect E404 = name free; upgrade: expect the previous version)
|
package/skills/plan/SKILL.md
CHANGED
|
@@ -376,9 +376,9 @@ The Epic issue's number is not known during § 5.5.1. Once Phase 6 creates it, s
|
|
|
376
376
|
|
|
377
377
|
Score each issue using three factors:
|
|
378
378
|
|
|
379
|
-
1. **Technical dependencies (highest weight):** Issues that other issues depend on get `priority
|
|
379
|
+
1. **Technical dependencies (highest weight):** Issues that other issues depend on get `priority::critical` or `priority::high`. Identify dependency chains: DB schema before API, API before frontend, shared libs before consumers, infrastructure before application.
|
|
380
380
|
|
|
381
|
-
2. **Business value (medium weight):** Issues the user marked as core MVP features in the PRD get `priority
|
|
381
|
+
2. **Business value (medium weight):** Issues the user marked as core MVP features in the PRD get `priority::high`. Nice-to-haves and polish items get `priority::medium` or `priority::low`.
|
|
382
382
|
|
|
383
383
|
3. **Risk (tiebreaker) — Impact × Risk 2×2 triage:** Classify each issue by Impact (high/low) and Risk (high/low) before applying the bump:
|
|
384
384
|
- **High-Impact + Low-Risk → Implement.** Proceed directly; apply the one-level priority bump from the tiebreaker rule.
|
|
@@ -387,7 +387,7 @@ Score each issue using three factors:
|
|
|
387
387
|
- **Low-Impact + High-Risk → Reject.** Do not create an issue for this candidate; note the rejection rationale in the PRD's Risks & Dependencies section instead.
|
|
388
388
|
|
|
389
389
|
Assign labels from the standard taxonomy:
|
|
390
|
-
- `priority
|
|
390
|
+
- `priority::critical` / `priority::high` / `priority::medium` / `priority::low`
|
|
391
391
|
- `type:feature` / `type:enhancement` / `type:bug` / `type:chore` / `type:discovery`
|
|
392
392
|
- `status:ready`
|
|
393
393
|
- `area:<inferred from content>` (e.g., `area:api`, `area:frontend`, `area:infra`)
|
|
@@ -422,8 +422,8 @@ If user selects "Adjust priorities" or "Remove issues", handle the adjustments i
|
|
|
422
422
|
For each approved issue:
|
|
423
423
|
|
|
424
424
|
1. Create via VCS CLI using comma-separated labels in a single `--label` flag:
|
|
425
|
-
- **GitLab**: `glab issue create --title "[Plan] <title>" --label "type:feature,priority
|
|
426
|
-
- **GitHub**: `gh issue create --title "[Plan] <title>" --label "type:feature,priority
|
|
425
|
+
- **GitLab**: `glab issue create --title "[Plan] <title>" --label "type:feature,priority::high,status:ready" --description "<body>"`
|
|
426
|
+
- **GitHub**: `gh issue create --title "[Plan] <title>" --label "type:feature,priority::high,status:ready" --body "<body>"`
|
|
427
427
|
2. Brief pause (1s) between creations for rate limiting
|
|
428
428
|
3. After all issues are created, set dependency links:
|
|
429
429
|
- **GitLab**: use `glab api` to set `blocks`/`is-blocked-by` relations. On HTTP 403 (non-Premium/Ultimate): `relates_to` + body-ordering-note fallback — see gitlab-ops SKILL.md § "Issue Linking (`blocks` / `is_blocked_by`)".
|
|
@@ -111,9 +111,9 @@ Source: PRD Section 3 (Acceptance Criteria).
|
|
|
111
111
|
|
|
112
112
|
Apply this scoring:
|
|
113
113
|
|
|
114
|
-
1. **Technical dependencies** — Issues that block other issues get `priority
|
|
115
|
-
2. **Core acceptance criteria** — Issues covering primary happy-path scenarios get `priority
|
|
116
|
-
3. **Edge cases / nice-to-haves** — Defensive scenarios, error handling, optional behaviors get `priority
|
|
114
|
+
1. **Technical dependencies** — Issues that block other issues get `priority::critical` or `priority::high`. DB before API, API before UI, shared before consumers.
|
|
115
|
+
2. **Core acceptance criteria** — Issues covering primary happy-path scenarios get `priority::high`.
|
|
116
|
+
3. **Edge cases / nice-to-haves** — Defensive scenarios, error handling, optional behaviors get `priority::medium` or `priority::low`.
|
|
117
117
|
4. **Risk factor — Impact × Risk 2×2 triage:** Classify by Impact (high/low) × Risk (high/low): **High-Impact + Low-Risk → Implement** (bump priority up one level); **High-Impact + High-Risk → Experiment** (smallest spike first); **Low-Impact + Low-Risk → Defer** (backlog, no issue in this set); **Low-Impact + High-Risk → Reject** (no issue — note rationale in § Risks & Dependencies). Full quadrant definitions: `SKILL.md` § 6.2 Auto-Prioritize.
|
|
118
118
|
|
|
119
119
|
### Labels
|
|
@@ -121,7 +121,7 @@ Apply this scoring:
|
|
|
121
121
|
Apply per gitlab-ops skill label taxonomy:
|
|
122
122
|
|
|
123
123
|
- **Type:** `type:feature` for new capabilities, `type:enhancement` for extensions of existing features.
|
|
124
|
-
- **Priority:** `priority
|
|
124
|
+
- **Priority:** `priority::critical` / `priority::high` / `priority::medium` / `priority::low` from auto-prioritize above.
|
|
125
125
|
- **Area:** Infer from affected code paths (e.g., `area:api`, `area:frontend`, `area:infra`).
|
|
126
126
|
- **Appetite:** Map from Wave 1 Q5 scope answer (`appetite:1w`, `appetite:2w`, `appetite:6w`).
|
|
127
127
|
|
package/skills/plan/mode-new.md
CHANGED
|
@@ -235,10 +235,10 @@ Score each issue using three factors:
|
|
|
235
235
|
|
|
236
236
|
1. **Technical dependencies (highest weight):**
|
|
237
237
|
- DB schema before API, API before frontend, shared libs before consumers.
|
|
238
|
-
- Issues that block others → `priority
|
|
238
|
+
- Issues that block others → `priority::critical` or `priority::high`.
|
|
239
239
|
2. **Business value (medium weight):**
|
|
240
|
-
- Core MVP features → `priority
|
|
241
|
-
- Nice-to-haves → `priority
|
|
240
|
+
- Core MVP features → `priority::high`.
|
|
241
|
+
- Nice-to-haves → `priority::medium` or `priority::low`.
|
|
242
242
|
3. **Risk (tiebreaker):**
|
|
243
243
|
- Issues with identified risks from PRD Section 7 → bump up one level.
|
|
244
244
|
|
|
@@ -249,12 +249,12 @@ Use taxonomy from `setup-gitlab-groups.sh`:
|
|
|
249
249
|
**Priority mapping for VCS labels:**
|
|
250
250
|
| Categorization | VCS Label |
|
|
251
251
|
|---|---|
|
|
252
|
-
| P0 (critical path, blocking) | `priority
|
|
253
|
-
| P1 (high impact, needed soon) | `priority
|
|
254
|
-
| P2 (medium, can wait) | `priority
|
|
255
|
-
| P3 (nice-to-have) | `priority
|
|
252
|
+
| P0 (critical path, blocking) | `priority::critical` |
|
|
253
|
+
| P1 (high impact, needed soon) | `priority::high` |
|
|
254
|
+
| P2 (medium, can wait) | `priority::medium` |
|
|
255
|
+
| P3 (nice-to-have) | `priority::low` |
|
|
256
256
|
|
|
257
|
-
Always use the `priority
|
|
257
|
+
Always use the `priority::<level>` format in VCS CLI commands, not P0/P1/P2/P3.
|
|
258
258
|
|
|
259
259
|
- **type:** feature, enhancement, bug, chore, docs
|
|
260
260
|
- **status:** `status:ready`
|
|
@@ -275,11 +275,11 @@ Use AskUserQuestion to present the full issue structure:
|
|
|
275
275
|
```bash
|
|
276
276
|
# Create epic
|
|
277
277
|
glab issue create --title "$EPIC_TITLE" --description "$EPIC_DESC" \
|
|
278
|
-
--label "type:epic,priority
|
|
278
|
+
--label "type:epic,priority::$PRIORITY" --milestone "$MILESTONE"
|
|
279
279
|
|
|
280
280
|
# Create sub-issues
|
|
281
281
|
glab issue create --title "$ISSUE_TITLE" --description "$ISSUE_DESC" \
|
|
282
|
-
--label "type:feature,priority
|
|
282
|
+
--label "type:feature,priority::$PRIORITY,status:ready,area:$AREA,appetite:$APPETITE"
|
|
283
283
|
```
|
|
284
284
|
|
|
285
285
|
### Step 6: Set dependency links
|
|
@@ -225,7 +225,7 @@ Before Phase 3.2, satisfy the PRD Commit Gate — see `SKILL.md` § Phase 5.5 (H
|
|
|
225
225
|
|
|
226
226
|
Create one VCS issue per agreed improvement from Wave 2:
|
|
227
227
|
- **Title**: `[Retro] <action description>`
|
|
228
|
-
- **Labels**: `type:enhancement`, `priority
|
|
228
|
+
- **Labels**: `type:enhancement`, `priority::<from ranking>`, `area:<inferred>`
|
|
229
229
|
- **Description**: action, impact, effort, link to retro document
|
|
230
230
|
- Create via VCS CLI (per gitlab-ops skill)
|
|
231
231
|
|
|
@@ -109,7 +109,7 @@ Commands:
|
|
|
109
109
|
4. Check changed files for debug artifacts: `console.log`, `debugger`, `TODO: remove`.
|
|
110
110
|
|
|
111
111
|
Behavior: BLOCKING. Do not commit if any check fails. Fix quick issues (<2 min) inline.
|
|
112
|
-
For anything longer, create a `priority
|
|
112
|
+
For anything longer, create a `priority::high` issue and proceed without committing the
|
|
113
113
|
affected files.
|
|
114
114
|
|
|
115
115
|
> **Broken-Window cross-reference (#730/H5):** a Full-Gate PASS that ships with a documented exception (echo-stub, WARN-lint, overridden finding) feeds session-end Phase 2.6 — see `skills/session-end/SKILL.md § Phase 2.6`.
|
|
@@ -35,6 +35,16 @@ any file is written. Advisory-only — rules are NEVER auto-applied.
|
|
|
35
35
|
- **Engine never writes `.claude/rules/`.** `runReconcile` computes proposals and records
|
|
36
36
|
them in the idempotency sidecar only. The only module that writes `.claude/rules/` is
|
|
37
37
|
`writer.mjs`, and only AFTER the operator approves proposals via AUQ.
|
|
38
|
+
- **The candidate store belongs to `mergeCandidates` — nothing else writes it.**
|
|
39
|
+
`.orchestrator/runtime/reconcile-candidates.jsonl` is a mutable work-queue whose only
|
|
40
|
+
sanctioned writer is `mergeCandidates` (`scripts/lib/reconcile/idempotency.mjs`); it is
|
|
41
|
+
not a scratch pad, and no report, analysis run, or agent may append to it by hand. A
|
|
42
|
+
hand-written record there corrupts downstream readers — the session-start reconcile nudge
|
|
43
|
+
banner derives "last run" from `created_at`, so a foreign-shaped record makes a non-empty
|
|
44
|
+
store report *no reconcile run on record*. Candidate analyses and dry-run reports write
|
|
45
|
+
their findings to `docs/reconcile/<date>-<topic>.md`, never into the store. (Since
|
|
46
|
+
2026-07-31 a read-side shape guard drops records lacking `learning_key`/`created_at` and
|
|
47
|
+
`mergeCandidates` reports the count as `skipped` — that guard is a backstop, not a licence.)
|
|
38
48
|
- **Same pipeline as session-end Phase 3.6.8.** This skill uses the identical engine and
|
|
39
49
|
writer seams as the automatic session-end reconciliation phase — operator experience is
|
|
40
50
|
consistent, and any fixes to the engine benefit both paths.
|
|
@@ -76,6 +86,7 @@ CONFIDENCE_FLOOR=$(echo "$CONFIG" | jq -r '.reconcile["confidence-floor"] // 0.5
|
|
|
76
86
|
RECONCILE_MODE=$(echo "$CONFIG" | jq -r '.reconcile.mode // "warn"')
|
|
77
87
|
MIN_RULE_DAYS=$(echo "$CONFIG" | jq -r '.reconcile["min-rule-days"] // 7')
|
|
78
88
|
MIN_INSIGHT_CHARS=$(echo "$CONFIG" | jq -r '.reconcile["min-insight-chars"] // 24')
|
|
89
|
+
MAX_PROPOSALS_PER_RUN=$(echo "$CONFIG" | jq -r '.reconcile["max-proposals-per-run"] // 10')
|
|
79
90
|
```
|
|
80
91
|
|
|
81
92
|
When `RULE_EXPIRY_DAYS` is empty, pass `ruleExpiryDays: undefined` to `runReconcile` so the engine uses its per-type TTL. Defaults when the `reconcile` block is absent or a field is missing:
|
|
@@ -86,6 +97,8 @@ When `RULE_EXPIRY_DAYS` is empty, pass `ruleExpiryDays: undefined` to `runReconc
|
|
|
86
97
|
near-dead or already-elapsed natural expiry never produces a born-dead rule (issue #741.1).
|
|
87
98
|
- `min-insight-chars`: 24 — opt-in minimum insight length gating the eligibility
|
|
88
99
|
placeholder-insight check (issue #741.2).
|
|
100
|
+
- `max-proposals-per-run`: 10 — volume brake (issue #900 D); the engine sorts eligible
|
|
101
|
+
learnings by confidence DESC and proposes at most this many per run.
|
|
89
102
|
|
|
90
103
|
Note: `reconcile.enabled` is intentionally NOT checked — this on-demand command always runs.
|
|
91
104
|
|
|
@@ -119,6 +132,7 @@ const { proposals, rejected, summary, error } = await runReconcile({
|
|
|
119
132
|
ruleExpiryDays: RULE_EXPIRY_DAYS, // empty → undefined → engine per-type TTL
|
|
120
133
|
minRuleDays: MIN_RULE_DAYS, // default 7 — floors a near-dead expires-at
|
|
121
134
|
minInsightChars: MIN_INSIGHT_CHARS, // default 24 — opt-in placeholder-insight length gate
|
|
135
|
+
maxProposalsPerRun: MAX_PROPOSALS_PER_RUN, // default 10 — volume brake (issue #900 D)
|
|
122
136
|
now: new Date(),
|
|
123
137
|
dryRun: DRY_RUN, // true → engine touches no disk (no idempotency sidecar write)
|
|
124
138
|
});
|
|
@@ -163,7 +177,10 @@ List `rejected[].reason` and exit.
|
|
|
163
177
|
|
|
164
178
|
**Only when `DRY_RUN=true`.**
|
|
165
179
|
|
|
166
|
-
Print the proposals in a readable table. Do NOT write the sidecar, do NOT render an AUQ
|
|
180
|
+
Print the proposals in a readable table. Do NOT write the sidecar, do NOT render an AUQ, and
|
|
181
|
+
do NOT write candidates into `.orchestrator/runtime/reconcile-candidates.jsonl` — that store
|
|
182
|
+
is `mergeCandidates`' alone (see Posture Contract). A dry-run write-up belongs in
|
|
183
|
+
`docs/reconcile/`.
|
|
167
184
|
|
|
168
185
|
```
|
|
169
186
|
## Reconcile — Dry Run (N proposals, M rejected)
|
|
@@ -307,9 +324,9 @@ If `written === 0` and `approved.length === 0`:
|
|
|
307
324
|
silently swallow failures.
|
|
308
325
|
- **ALWAYS** present proposals in batches of ≤4 via AUQ multiSelect — mirrors session-end
|
|
309
326
|
3.6.3 / 3.6.8 and keeps the operator prompt readable.
|
|
310
|
-
- **ALWAYS** honour `confidence-floor`, `rule-expiry-days`, `min-rule-days`,
|
|
311
|
-
`min-insight-chars` from Session Config `reconcile` block —
|
|
312
|
-
the skill must pass them explicitly.
|
|
327
|
+
- **ALWAYS** honour `confidence-floor`, `rule-expiry-days`, `min-rule-days`,
|
|
328
|
+
`min-insight-chars`, and `max-proposals-per-run` from Session Config `reconcile` block —
|
|
329
|
+
the engine reads these, but the skill must pass them explicitly.
|
|
313
330
|
|
|
314
331
|
## Anti-Patterns
|
|
315
332
|
|
|
@@ -74,7 +74,7 @@ Read back the session plan that was agreed at the start. For EACH planned item:
|
|
|
74
74
|
- Document what was completed and what remains
|
|
75
75
|
- **Do NOT file the carryover issue here (#769).** Collect a carryover **candidate** instead — append it to the in-memory candidate list that the Phase 1.65 Handover Alignment Gate consumes. The issue is filed (only if the gate confirms it) in Phase 5 Step 3. Candidate record (JS keys as `routeCandidates` / `normalizeCandidate` read them — `source-phase`→`sourcePhase`, `origin-issue`→`originIssue`; see `plan-verification.md § Candidate Record Format`):
|
|
76
76
|
- `{ task: '<original task description>', sourcePhase: '1.2', originIssue: <IID or null>, priority: '<original>', bucket: 'partially-done' }`
|
|
77
|
-
- The eventual issue keeps the source-specific `[Carryover]` template — Title `[Carryover] <original task description>`, Labels `priority
|
|
77
|
+
- The eventual issue keeps the source-specific `[Carryover]` template — Title `[Carryover] <original task description>`, Labels `priority::<original>` + `status:ready`, Description = what's done / what's left / context for next session.
|
|
78
78
|
- Link to the original issue when applicable (record its IID as `originIssue`; a candidate with no origin issue auto-carries per the gate's routing, so nothing planned is silently forgotten).
|
|
79
79
|
|
|
80
80
|
### 1.3 Not Started Items
|
|
@@ -218,7 +218,7 @@ node scripts/emit-event.mjs --type orchestrator.handover.gated --payload \
|
|
|
218
218
|
const { autoCarry, ask } = routeCandidates(candidates);
|
|
219
219
|
```
|
|
220
220
|
|
|
221
|
-
`autoCarry` = `priority
|
|
221
|
+
`autoCarry` = `priority::critical|high` OR `bucket === 'spiral-failed'` OR `originIssue === null` — **non-deselectable** (dropping any of these would be real forgetting; consistent with the Critical Rule at `SKILL.md:853`). `ask` = the middle-band (priority `medium`/`low`/none WITH an origin issue, buckets not-started/emergent/partially-done) plus any `malformed` record. `routeCandidates` returns NORMALIZED copies for gate rendering; the coordinator retains its ORIGINAL candidate objects (with filing payloads) for Phase 5 Step 3.
|
|
222
222
|
|
|
223
223
|
3. Read STATE.md contents and extract the open questions via the sibling helper:
|
|
224
224
|
|
|
@@ -313,10 +313,10 @@ Dispatch the session-reviewer agent to verify implementation quality before the
|
|
|
313
313
|
|
|
314
314
|
| Finding class | Disposition |
|
|
315
315
|
|---|---|
|
|
316
|
-
| HIGH+ / blocking review finding | Fix inline if quick (<2 min); else create an issue (`priority
|
|
316
|
+
| HIGH+ / blocking review finding | Fix inline if quick (<2 min); else create an issue (`priority::high`, `status:ready`) and note it in the Final Report |
|
|
317
317
|
| MED / LOW review finding | Fold in-session if quick; else record under "Unresolved Review Findings" in the Final Report — DO NOT create an issue (#617) |
|
|
318
318
|
| Planned-carryover (item was in the plan, not finished) | Route as a carryover **candidate** per Phase 1.2 → the Phase 1.65 gate files it. Never forgotten: a no-origin/critical/high item auto-carries as a `[Carryover]` issue; a middle-band item with an origin issue is preselected=carry (and its origin issue stays open even if dropped). |
|
|
319
|
-
| SPIRAL / FAILED agent carryover | Route as an **auto-carry** candidate per Phase 1.6 → filed via `createSpiralCarryoverIssue` in Phase 5 Step 3 (non-deselectable) |
|
|
319
|
+
| SPIRAL / FAILED agent carryover | Route as an **auto-carry** candidate per Phase 1.6 → filed via `createSpiralCarryoverIssue` in Phase 5 Step 3 (non-deselectable; **exempt from the `issue-budget` cap** — the `[Carryover] [SPIRAL\|FAILED]` title and the `type::carryover` label bypass it, so a full budget can never swallow this filing) |
|
|
320
320
|
|
|
321
321
|
**Override-ratio telemetry (#730/H5):** whenever one or more MED/LOW review findings are routed to "Unresolved Review Findings" (rather than fixed), additionally emit a single event capturing how many findings were absorbed rather than resolved — feeding the `override_ratio` metric:
|
|
322
322
|
|
|
@@ -364,7 +364,7 @@ Rules:
|
|
|
364
364
|
|
|
365
365
|
> **Verification Reference:** See `verification-checklist.md` in this skill directory for the full quality gate checklist.
|
|
366
366
|
|
|
367
|
-
Run ALL checks listed in the verification checklist. If any check fails: fix if quick (<2 min), otherwise create a `priority
|
|
367
|
+
Run ALL checks listed in the verification checklist. If any check fails: fix if quick (<2 min), otherwise create a `priority::high` issue. Do NOT commit broken code.
|
|
368
368
|
|
|
369
369
|
### Phase 2.0a: Echo-Stub Detection (GH #42)
|
|
370
370
|
|
|
@@ -438,7 +438,7 @@ totalFindings = projectStaleness.findings.length + narrativeStaleness.findings.l
|
|
|
438
438
|
- If `totalFindings === 0`: continue, log `Vault staleness: clean (mode=strict)`.
|
|
439
439
|
- If `totalFindings > 0`: do NOT block the close. Present the findings list and surface an AskUserQuestion whose Recommended default is **warn + carryover + continue**:
|
|
440
440
|
- On Claude Code: AskUserQuestion with options:
|
|
441
|
-
1. "Warn + carryover and close (Recommended)" — file a carryover issue (labels `carryover`, `priority
|
|
441
|
+
1. "Warn + carryover and close (Recommended)" — file a carryover issue (labels `carryover`, `priority::high`) titled `[Carryover] Vault staleness (strict) — <count> findings` documenting the stale projects/narratives for a follow-up session, log a Deviation entry in STATE.md `## Deviations`, then continue the close:
|
|
442
442
|
`- [<ISO timestamp>] Phase 2.3: Vault staleness strict-mode findings carried over. Findings: <count> (projects: <N>, narratives: <M>) → issue #<IID>.`
|
|
443
443
|
2. "Override and close" — proceed without a carryover issue, log a Deviation entry in STATE.md `## Deviations`:
|
|
444
444
|
`- [<ISO timestamp>] Phase 2.3: Vault staleness strict-mode findings overridden by user. Findings: <count> (projects: <N>, narratives: <M>).`
|
|
@@ -480,7 +480,7 @@ For each kept phase:
|
|
|
480
480
|
- exit code `≠ 0` ⇒ **BLOCK the close** using the same routing pattern as Phase 2.3 strict-mode. `mode: hard` here is an operator-declared repo contract (the repo deliberately chose `mode: hard`), so the block semantics are preserved — but the AUQ now ALSO offers a warn + carryover escape hatch. Present the phase name + captured summary and offer:
|
|
481
481
|
- On Claude Code: AskUserQuestion with options:
|
|
482
482
|
1. "Fix and retry Phase 2.5" (Recommended) — exit close, let the user investigate.
|
|
483
|
-
2. "Warn + carryover and close" — file a carryover issue (labels `carryover`, `priority
|
|
483
|
+
2. "Warn + carryover and close" — file a carryover issue (labels `carryover`, `priority::high`) titled `[Carryover] custom-phase '<name>' (mode=hard) exited <code>` capturing the phase name + captured summary for a follow-up session, log the Deviation entry, then continue the close.
|
|
484
484
|
3. "Override and close" — proceed, log a Deviation entry in STATE.md `## Deviations`:
|
|
485
485
|
`- [<ISO timestamp>] Phase 2.5: custom-phase '<name>' (mode=hard) exited <code>, overridden by user.`
|
|
486
486
|
In addition to the Deviation entry, emit an override-ratio event so the override feeds the `override_ratio` metric (#730/H5): `node scripts/emit-event.mjs --type orchestrator.finding.overridden --payload '{"phase":"2.5","kind":"custom-phase-hard","count":N}'`.
|
|
@@ -507,7 +507,7 @@ already-computed results — no new detection logic, only aggregation:
|
|
|
507
507
|
4. Wave-level reviewer findings overridden without a fix task (`## Deviations` entries matching `reviewer finding overridden` — written by wave-executor §5/5a).
|
|
508
508
|
|
|
509
509
|
For EACH item: file a hard-terminated closure issue via `createBrokenWindowIssue()`
|
|
510
|
-
from `scripts/lib/spiral-carryover.mjs` — labels `broken-window` + `priority
|
|
510
|
+
from `scripts/lib/spiral-carryover.mjs` — labels `broken-window` + `priority::high`,
|
|
511
511
|
due-date = today + `broken-window-budget.due-days` (default 7; `glab` native
|
|
512
512
|
`--due-date`, `gh` fallback: `Due: <date>` as first body line — GitHub has no
|
|
513
513
|
native due-date field). Idempotent per task-hash — re-running a close never
|
|
@@ -986,8 +986,8 @@ if (sweep) {
|
|
|
986
986
|
The call is idempotent: if the issue has no `status:*` labels, no update CLI call is made. Failures from `stripStatusLabels` are non-fatal — log and proceed with close.
|
|
987
987
|
|
|
988
988
|
2. **Update in-progress issues**: ensure labels reflect actual state using the issue update command
|
|
989
|
-
3. **Create carryover issues — from the Phase 1.65 gate's carry-list ONLY (#769):** file an issue for each item on the carry-list produced by the Handover Alignment Gate — i.e. the non-deselectable **auto-carry** class (`priority
|
|
990
|
-
- **Template stays source-specific:** 1.2 Partially-Done → `[Carryover] <task>` (labels `priority
|
|
989
|
+
3. **Create carryover issues — from the Phase 1.65 gate's carry-list ONLY (#769):** file an issue for each item on the carry-list produced by the Handover Alignment Gate — i.e. the non-deselectable **auto-carry** class (`priority::critical|high`, SPIRAL/FAILED, or no-origin-issue candidates) PLUS the middle-band items the operator LEFT SELECTED in triage. Do NOT file anything the gate dropped, and do NOT file directly from Phase 1.2/1.3/1.4/1.6 — those phases only collected candidates.
|
|
990
|
+
- **Template stays source-specific:** 1.2 Partially-Done → `[Carryover] <task>` (labels `priority::<original>`, `status:ready`); 1.4 unfinished Emergent → a **normal** issue (NOT the `[Carryover]` template); 1.6 SPIRAL/FAILED → fire the deferred `createSpiralCarryoverIssue({ taskDescription, kind, context, priority: 'high', vcs })` (idempotent task-hash dedup — payload comes from the candidate's `_spiral` annotation set in Phase 1.6 step 5). 1.3 files no NEW issue: a carried 1.3 candidate simply keeps its ORIGINAL issue `status:ready`.
|
|
991
991
|
- **Dropped middle-band items:** file NO `[Carryover]` duplicate; the origin issue stays open and unchanged. Record each drop in the Phase 6 Final Report under `### Dropped at Handover Gate` with its origin-issue reference and a reason slot.
|
|
992
992
|
- **Fail-open / gate skipped:** when Phase 1.65 skipped fail-open, the carry-list is ALL candidates (status quo) and there is no drop-list.
|
|
993
993
|
- **Mark answered open questions `[x]` durably — atomic with the filing above (#769):** now, on the completed side of the Quality Gate, persist each answered open question captured in-memory at Phase 1.65 Step 4 to STATE.md via the lock-guarded sibling helper (PSA-005). Co-locating this write with the carryover-issue filing is the load-bearing correctness invariant: an earlier Quality-Gate abort leaves every question `- [ ]` on disk, so it correctly re-surfaces via `readOpenQuestions().filter(!answered)` on re-close — the `[x]` mark now reflects a COMPLETED handover, never a mid-close state a later abort would invalidate. Any implied-work candidate an answered question enqueued in Phase 1.65 is filed by the carry-list step above, so the mark and its issue land together:
|
|
@@ -1002,13 +1002,32 @@ if (sweep) {
|
|
|
1002
1002
|
|
|
1003
1003
|
Fail-open: a `markOpenQuestionAnsweredOnDisk` failure is non-fatal — log a WARN and proceed with the close; the question simply stays `- [ ]` and roundtrips to the next session.
|
|
1004
1004
|
|
|
1005
|
+
3b. **Drain the issue-budget overflow — exactly ONE collector artefact (issue-budget):** when `.orchestrator/runtime/issue-budget.json` has a non-empty `overflow[]`, the session hit its `issue-budget.max-per-session` cap and every over-cap creation was PARKED rather than filed. Fold the whole list into a single artefact so nothing is silently dropped.
|
|
1006
|
+
|
|
1007
|
+
**Ordering (load-bearing):** run this as the LAST issue-creating action of Phase 5 — after step 3, after "Discovery Issue Creation", after step 4 — and re-read the counter file at that moment. Those steps can themselves push new entries into `overflow[]`; draining early would leave them unfiled.
|
|
1008
|
+
|
|
1009
|
+
```js
|
|
1010
|
+
import { readBudgetState, budgetStatePath } from '${PLUGIN_ROOT}/scripts/lib/issue-budget.mjs';
|
|
1011
|
+
const state = readBudgetState(repoRoot, sessionId); // { sessionId, count, exempt, overflow: [...] }
|
|
1012
|
+
```
|
|
1013
|
+
|
|
1014
|
+
- **`issue-budget.overflow: collect-issue` (default)** — create exactly ONE issue:
|
|
1015
|
+
- Title: `[Backlog-Sammel] <session-id>, <N> zurückgestellte Punkte`
|
|
1016
|
+
- Labels: `type::backlog`, `priority::low`
|
|
1017
|
+
- Body: a Markdown checklist with one `- [ ]` line per `overflow[]` entry (`title` when present, otherwise the truncated `command`, plus its `at` timestamp).
|
|
1018
|
+
- This collector issue is itself EXEMPT from the cap (`[Backlog-Sammel]` is in the exemption list in `scripts/lib/issue-budget.mjs`), so it always lands even at count == max.
|
|
1019
|
+
- **`issue-budget.overflow: vault-note`** — create NO issue. Write one Markdown file `vault/00-inbox/<session-id>-backlog-sammel.md` (path relative to `vault-integration.vault-dir`) with valid vault frontmatter and the same checklist body.
|
|
1020
|
+
- After the artefact exists, reset `overflow` to `[]` in the counter file and record the collector issue ID / note path in the Phase 6 Final Report under `### Zurückgestellt (issue-budget)`.
|
|
1021
|
+
- **Never exempt-by-accident:** the cap never applied to `priority::critical`, the carryover class (`[Carryover]`, SPIRAL/FAILED, `type::carryover`), or `broken-window` closure issues, so nothing on the Phase 1.65 carry-list can ever appear in `overflow[]`. The promises at Phase 1.8 ("SPIRAL / FAILED agent carryover … non-deselectable") and the Critical Rule "ALWAYS create issues for unfinished PLANNED work" stay intact by construction.
|
|
1022
|
+
- Fail-open: a missing or malformed counter file means "no overflow" — log a WARN and continue the close.
|
|
1023
|
+
|
|
1005
1024
|
#### Discovery Issue Creation (if discovery ran in Phase 1.5)
|
|
1006
1025
|
|
|
1007
1026
|
For each finding with severity `critical` or `high` from Phase 1.5:
|
|
1008
1027
|
1. Create a VCS issue using the detected platform CLI:
|
|
1009
1028
|
- Title: `[Discovery] <description>` (truncated to 70 chars)
|
|
1010
1029
|
- Body: `**Probe:** <probe>\n**File:** <file>:<line>\n**Severity:** <severity>\n**Confidence:** <confidence>%\n**Recommendation:** <recommendation>`
|
|
1011
|
-
- Labels: `type:discovery`, `priority
|
|
1030
|
+
- Labels: `type:discovery`, `priority::<severity>` (critical→critical, high→high)
|
|
1012
1031
|
2. Log each created issue ID for the Final Report
|
|
1013
1032
|
3. Update `discovery_stats.issues_created` count
|
|
1014
1033
|
|
|
@@ -1050,7 +1069,7 @@ Present to the user:
|
|
|
1050
1069
|
- Wave 1 (Discovery): [duration] — [N agents] — [K files]
|
|
1051
1070
|
- Wave 2 (Impl-Core): [duration] — [N agents] — [K files]
|
|
1052
1071
|
- ...
|
|
1053
|
-
- Tests: [passing/total]
|
|
1072
|
+
- Tests: [passing/total] · Δ this session: +[added] / −[removed] / ~[consolidated] · tests:src LOC ratio [x.xx] (advisory ceiling 1.60)
|
|
1054
1073
|
- TypeScript: 0 errors
|
|
1055
1074
|
- Commits: [N] pushed to [branch]
|
|
1056
1075
|
- Mirror: [synced/skipped]
|
|
@@ -1072,6 +1091,8 @@ Present to the user:
|
|
|
1072
1091
|
- Notes: [any context for next session]
|
|
1073
1092
|
```
|
|
1074
1093
|
|
|
1094
|
+
> **Test-delta anchor:** the `Δ this session` figures are aggregated from the `test_delta` field of this session's agent reports (added / removed / consolidated test cases); the `tests:src LOC ratio` is `wc -l` over `tests/` divided by `wc -l` over `scripts/` + `hooks/`. A bare `passing/total` count is not a progress signal — a growing suite reads as progress even when the growth is redundant, which is exactly why the delta and the ratio are reported alongside it. When the ratio exceeds the advisory ceiling, recommend that the NEXT session's Quality wave run as a **consolidation wave**: no new test lands without a redundant one being removed in the same change. This is advisory only — it never blocks the close.
|
|
1095
|
+
|
|
1075
1096
|
> **Documentation Coverage anchor:** If Phase 3.2 ran and produced task verification results (i.e. `docs-orchestrator.enabled: true` and `docs-tasks` were found), the results appear here as a `### Documentation Coverage (docs-orchestrator)` subsection emitted by Phase 3.2 Step 7. The content is written dynamically — it is not pre-populated in this template. When `docs-orchestrator.enabled` is `false` or `docs-tasks` were absent, this subsection is omitted entirely.
|
|
1076
1097
|
|
|
1077
1098
|
## Sub-File Reference
|
|
@@ -1110,7 +1131,7 @@ Present to the user:
|
|
|
1110
1131
|
- **NEVER commit with TypeScript errors** — 0 errors is non-negotiable
|
|
1111
1132
|
- **NEVER use `git add .`** — stage files individually to avoid capturing parallel session work
|
|
1112
1133
|
- **NEVER skip issue updates** — VCS must reflect reality after every session
|
|
1113
|
-
- **ALWAYS create issues for unfinished PLANNED work** — SPIRAL/FAILED agent carryover and partially-done plan items (Phase 1.2 / 1.6) ALWAYS get a ticket; nothing planned-but-unfinished is "remembered" without one.
|
|
1134
|
+
- **ALWAYS create issues for unfinished PLANNED work** — SPIRAL/FAILED agent carryover and partially-done plan items (Phase 1.2 / 1.6) ALWAYS get a ticket; nothing planned-but-unfinished is "remembered" without one. The `issue-budget` per-session cap does NOT weaken this: `priority::critical`, the carryover class (`[Carryover]`, `[SPIRAL]`/`[FAILED]`, `type::carryover`, bare `carryover`) and `broken-window` closure issues are exempt from the cap by construction (`scripts/lib/issue-budget.mjs` `EXEMPT_RULES`). Non-exempt over-cap creations are not dropped either — they are parked and folded into one `[Backlog-Sammel]` collector in Phase 5 Step 3b.
|
|
1114
1135
|
- **DO NOT auto-file MED/LOW review findings as issues** — newly-surfaced reviewer findings (Phase 1.8 / W4 panel) at MED or LOW severity are folded in-session or recorded in the Final Report under "Unresolved Review Findings". Only HIGH+/blocking review findings get an issue. (Issue #617 — stops the self-referential low-priority backlog.)
|
|
1115
1136
|
- **ALWAYS push to origin** — local-only work is lost work
|
|
1116
1137
|
- **ALWAYS mirror to GitHub** if configured — keep mirrors in sync
|