session-orchestrator 4.1.0 → 4.2.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/.agents/skills/session-plan/SKILL.md +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.codex-plugin/skills/session-plan/SKILL.md +1 -1
- package/.cursor/skills/session-plan/SKILL.md +1 -1
- package/.cursor-plugin/plugin.json +1 -1
- package/CHANGELOG.md +34 -0
- package/README.md +8 -8
- package/agents/ux-evaluator.md +1 -1
- package/commands/close.md +3 -3
- package/commands/go.md +2 -0
- package/commands/memory-cleanup.md +4 -3
- package/commands/persona-panel.md +1 -1
- package/commands/session.md +3 -2
- package/docs/README.md +4 -4
- package/docs/USER-GUIDE.md +115 -48
- package/docs/agent-authoring.md +2 -2
- package/docs/baseline.md +55 -1
- package/docs/ci-setup.md +1 -1
- package/docs/codex-setup.md +1 -0
- package/docs/components.md +2 -2
- package/docs/cursor-setup.md +1 -0
- package/docs/events-schema.md +4 -1
- package/docs/instruction-delivery.md +1 -1
- package/docs/memory-proposal-flow.md +3 -3
- package/docs/migration-v4.md +2 -2
- package/docs/owner-config-schema.md +74 -90
- package/docs/persona-panel.md +4 -4
- package/docs/pi-setup.md +1 -0
- package/docs/rule-authoring.md +13 -6
- package/docs/scope-collision-guard.md +2 -0
- package/docs/session-config-reference.md +55 -22
- package/docs/session-config-template.md +9 -5
- package/docs/vault-docs-architecture.md +4 -2
- package/hooks/_lib/hook-import-set.json +28 -3
- package/hooks/_lib/vcs-create-matcher.mjs +214 -16
- package/hooks/hooks-codex.json +1 -1
- package/hooks/hooks.json +1 -1
- package/hooks/pre-bash-issue-budget.mjs +123 -26
- package/hooks/subagent-telemetry.mjs +106 -20
- package/package.json +4 -4
- package/scripts/baseline-archetypes.mjs +28 -0
- package/scripts/lib/auto-dialectic.mjs +0 -68
- package/scripts/lib/baseline-archetypes.mjs +439 -0
- package/scripts/lib/build-live-signals.mjs +5 -6
- package/scripts/lib/config/issue-budget.mjs +68 -8
- package/scripts/lib/config/private-config-dir.mjs +3 -2
- package/scripts/lib/config/remote-hosts.mjs +2 -2
- package/scripts/lib/config-schema.mjs +79 -0
- package/scripts/lib/file-lock.mjs +47 -5
- package/scripts/lib/issue-budget-reconcile.mjs +392 -0
- package/scripts/lib/issue-budget.mjs +76 -3
- package/scripts/lib/learnings/evolve-telemetry.mjs +1 -2
- package/scripts/lib/maintenance-due-banner.mjs +440 -0
- package/scripts/lib/owner-config.example.yaml +29 -46
- package/scripts/lib/owner-yaml.mjs +14 -13
- package/scripts/lib/quality-gate.mjs +13 -6
- package/scripts/lib/resource-probe/evaluate.mjs +19 -21
- package/scripts/lib/rules-sync.mjs +34 -4
- package/scripts/lib/session-close-backfill.mjs +182 -40
- package/scripts/lib/session-end/phase-skip.mjs +85 -86
- package/scripts/lib/session-end/tail-runner.mjs +178 -0
- package/scripts/lib/session-schema/constants.mjs +6 -0
- package/scripts/lib/session-schema/validator.mjs +20 -0
- package/scripts/lib/session-shape.mjs +558 -0
- package/scripts/lib/session-start-probes.mjs +10 -3
- package/scripts/lib/session-token-rollup.mjs +95 -10
- package/scripts/lib/state-md/frontmatter-mutators.mjs +22 -34
- package/scripts/lib/state-md.mjs +1 -0
- package/scripts/lib/subagents-schema.mjs +77 -9
- package/scripts/lib/telemetry/pricing.mjs +197 -0
- package/scripts/lib/telemetry/sync.mjs +50 -1
- package/scripts/lib/validate/check-skill-script-paths.mjs +33 -10
- package/scripts/lib/validate/check-unwired-features.mjs +8 -7
- package/scripts/lib/vault-mirror/process.mjs +2 -1
- package/scripts/lib/vault-status/narrative-mirror.mjs +4 -4
- package/scripts/lib/wave-resource-gate.mjs +23 -27
- package/scripts/lib/wave-sizing.mjs +10 -3
- package/scripts/materialize-wave-scope.mjs +68 -14
- package/scripts/print-applicable-rules.mjs +7 -6
- package/scripts/print-learnings-index.mjs +3 -2
- package/scripts/session-shape.mjs +266 -0
- package/skills/_shared/config-reading.md +15 -9
- package/skills/_shared/private-capability-context.md +89 -0
- package/skills/bootstrap/SKILL.md +61 -13
- package/skills/bootstrap/_shared-template.md +99 -14
- package/skills/bootstrap/deep-template.md +36 -26
- package/skills/bootstrap/fast-template.md +44 -8
- package/skills/bootstrap/intensity-heuristic.md +10 -4
- package/skills/bootstrap/private-contract.md +119 -0
- package/skills/bootstrap/public-fallback.md +30 -18
- package/skills/bootstrap/standard-template.md +39 -24
- package/skills/discovery/probes-ui.md +1 -1
- package/skills/docs-orchestrator/audience-mapping.md +1 -1
- package/skills/evolve/SKILL.md +2 -2
- package/skills/gitlab-ops/SKILL.md +3 -3
- package/skills/grill/SKILL.md +1 -1
- package/skills/memory-cleanup/SKILL.md +2 -2
- package/skills/plan/mode-new.md +9 -0
- package/skills/reconcile/SKILL.md +1 -1
- package/skills/session-end/SKILL.md +3 -2
- package/skills/session-end/phase-3-2-docs-verification.md +1 -1
- package/skills/session-end/phase-3-6-tail.md +23 -65
- package/skills/session-end/phase-3-7a-recommendations.md +2 -2
- package/skills/session-end/references/phase-3-documentation-updates.md +8 -6
- package/skills/session-end/references/phase-5-issue-cleanup.md +26 -0
- package/skills/session-end/session-metrics-write.md +31 -12
- package/skills/session-plan/SKILL.md +56 -48
- package/skills/session-plan/wave-template.md +8 -15
- package/skills/session-start/SKILL.md +18 -2
- package/skills/session-start/phase-2-5-docs-planning.md +1 -1
- package/skills/session-start/phase-8-5-express-path.md +12 -9
- package/skills/session-start/references/phase-1-5-session-continuity.md +2 -0
- package/skills/session-start/references/phase-4-ssot-environment-check.md +21 -5
- package/skills/session-start/references/phase-6-7-memory-banner-telemetry-consent.md +3 -1
- package/skills/test-runner/rubric-v1.md +2 -2
- package/skills/wave-executor/SKILL.md +42 -12
- package/skills/wave-executor/circuit-breaker.md +3 -1
- package/skills/wave-executor/references/wave-loop-dispatch.md +4 -2
- package/skills/wave-executor/references/wave-loop-review.md +1 -1
- package/skills/wave-executor/references/wave-loop-scope-manifest.md +6 -2
- package/templates/nextjs-minimal/package.json +1 -1
- package/templates/node-minimal/package.json +1 -1
- package/scripts/lib/multi-provider-build/providers.mjs +0 -64
- package/scripts/lib/multi-provider-build/templating.mjs +0 -130
- package/scripts/lib/owner-config/coerce.mjs +0 -29
- package/scripts/lib/owner-config/constants.mjs +0 -21
- package/scripts/lib/owner-config/defaults.mjs +0 -50
- package/scripts/lib/owner-config/error.mjs +0 -19
- package/scripts/lib/owner-config/index.mjs +0 -13
- package/scripts/lib/owner-config/merge.mjs +0 -52
- package/scripts/lib/owner-config/validate.mjs +0 -259
- package/scripts/lib/owner-config-loader.mjs +0 -170
- package/scripts/lib/owner-config.mjs +0 -28
- package/scripts/lib/soul-resolve.mjs +0 -130
- package/scripts/lib/vault-mirror/render.mjs +0 -8
|
@@ -5,32 +5,38 @@
|
|
|
5
5
|
|
|
6
6
|
## Step 1: Detect PATH_TYPE (Silent — No User Interaction)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Run the dependency-free local contract reader. It uses the existing configuration
|
|
9
|
+
resolvers, with precedence `SO_BASELINE_PATH` → matching named baseline →
|
|
10
|
+
`owner.yaml` `paths.baseline-path` → committed Session Config. Paths resolve
|
|
11
|
+
host-locally and are never written into the contract result.
|
|
9
12
|
|
|
10
13
|
```bash
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
BOOTSTRAP_CONTRACT=$(node "$PLUGIN_ROOT/scripts/baseline-archetypes.mjs" --repo "$REPO_ROOT") || exit 2
|
|
15
|
+
PATH_TYPE=$(printf '%s' "$BOOTSTRAP_CONTRACT" | node --input-type=module -e '
|
|
16
|
+
let input = ""; for await (const chunk of process.stdin) input += chunk;
|
|
17
|
+
process.stdout.write(JSON.parse(input).status);
|
|
18
|
+
')
|
|
19
|
+
export BOOTSTRAP_CONTRACT PATH_TYPE
|
|
14
20
|
```
|
|
15
21
|
|
|
16
|
-
|
|
22
|
+
| Reader outcome | Bootstrap behavior |
|
|
23
|
+
|----------------|--------------------|
|
|
24
|
+
| No configured baseline, empty value, or missing directory | `public`; use bundled templates |
|
|
25
|
+
| Existing baseline with valid reduced schema v1 export | `private`; retain `archetypes` and `selected` |
|
|
26
|
+
| Existing baseline with missing CLI, invalid export, unsafe source, or producer failure | Abort; report the sanitized error reason |
|
|
27
|
+
| Valid private contract but no matching repository markers | `private`, `selected: null`; require selection for Standard/Deep |
|
|
17
28
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
| `plan-baseline-path` key is present but value is empty | `public` |
|
|
22
|
-
| Key is present, value is non-empty, AND `test -d "$BASELINE_PATH"` succeeds | `private` |
|
|
23
|
-
| Key is present, value is non-empty, BUT path does not exist on disk | `public` |
|
|
24
|
-
|
|
25
|
-
Set `PATH_TYPE = private | public`. Do not report this detection to the user — it is silent.
|
|
26
|
-
|
|
27
|
-
> **Note on rules-fetch (Phase 3.5 of SKILL.md):** The optional rules-fetch step runs regardless of `PATH_TYPE`. Both private (with `plan-baseline-path` set) and public (without it) repos can opt into the fetch by setting `baseline-ref` in Session Config. The fetch is independent of how the initial scaffold was generated.
|
|
28
|
-
|
|
29
|
-
---
|
|
29
|
+
Lookup is offline and read-only. A broken configured contract never silently
|
|
30
|
+
switches to a public archetype. Missing directories retain the established
|
|
31
|
+
public fallback. Never guess a baseline path or fetch one automatically.
|
|
30
32
|
|
|
31
33
|
## Private Path
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
Read and execute [`private-contract.md`](private-contract.md): use its selection,
|
|
36
|
+
staged scaffold, command/CI expectations, and S99 rule projection. Keep
|
|
37
|
+
`CONFIRMED_ARCHETYPE` as the validated contract ID throughout the tier flow.
|
|
38
|
+
The optional remote rules fetch is only a public-path opt-in; a configured
|
|
39
|
+
private baseline supplies selected rules locally.
|
|
34
40
|
|
|
35
41
|
---
|
|
36
42
|
|
|
@@ -38,6 +44,12 @@ When `PATH_TYPE = private`, the baseline templates are used directly. No new log
|
|
|
38
44
|
|
|
39
45
|
When `PATH_TYPE = public`, no `projects-baseline` is available. Use the plugin-bundled templates and platform-appropriate CLAUDE.md generation described below.
|
|
40
46
|
|
|
47
|
+
For each file newly created by these steps, append its relative filename to the
|
|
48
|
+
existing `BOOTSTRAP_FILES` array. This includes instruction files, minimal
|
|
49
|
+
README/gitignore files and each copied template file. Preserve the accumulated
|
|
50
|
+
array through inherited tiers; never append a directory or an existing owner
|
|
51
|
+
file just because it is present.
|
|
52
|
+
|
|
41
53
|
### Detect Platform
|
|
42
54
|
|
|
43
55
|
Read the current platform using the patterns from `skills/_shared/platform-tools.md`:
|
|
@@ -5,6 +5,20 @@
|
|
|
5
5
|
|
|
6
6
|
Standard tier is a strict superset of Fast tier. Execute all Fast-tier steps first, then the Standard-specific steps below.
|
|
7
7
|
|
|
8
|
+
Track actual newly created relative files in one `BOOTSTRAP_FILES` array across
|
|
9
|
+
all inherited steps. Append each file when created; preserve the array across
|
|
10
|
+
repeated steps. Never append an existing owner file or a directory.
|
|
11
|
+
|
|
12
|
+
## Private Contract Preparation
|
|
13
|
+
|
|
14
|
+
When `PATH_TYPE = private`, resolve `CONFIRMED_ARCHETYPE` with
|
|
15
|
+
`private-contract.md` and execute its Scaffold section **before** the inherited
|
|
16
|
+
Fast steps. Preserve its rendered metadata, manifests, source, README and CI.
|
|
17
|
+
Add its reported created files to `BOOTSTRAP_FILES`. Skip the four public
|
|
18
|
+
archetype sections below, then continue at Step 3a, S99 and the lock/quality-policy
|
|
19
|
+
steps. Populate command expectations from the selected contract as described
|
|
20
|
+
in `private-contract.md`.
|
|
21
|
+
|
|
8
22
|
## Step 1–7: Execute Fast Tier
|
|
9
23
|
|
|
10
24
|
Read and execute `skills/bootstrap/fast-template.md` Steps 1–7 in full. Do not skip any step. The Fast commit (`chore: bootstrap (fast)`) is NOT made — Fast steps produce files only; the single commit happens at Standard Step 7 below.
|
|
@@ -21,9 +35,9 @@ Before executing the stack-specific steps, resolve the final archetype:
|
|
|
21
35
|
ARCHETYPE = CONFIRMED_ARCHETYPE # set by SKILL.md from intensity-heuristic or user selection
|
|
22
36
|
```
|
|
23
37
|
|
|
24
|
-
|
|
38
|
+
For `PATH_TYPE = public`, valid values are `static-html` | `node-minimal` | `nextjs-minimal` | `python-uv`. Private IDs come only from the validated contract.
|
|
25
39
|
|
|
26
|
-
|
|
40
|
+
On the public path only, if `ARCHETYPE` is `null` or unset, default to `node-minimal`. A private missing/invalid selection aborts before scaffolding; it never reaches the public sections.
|
|
27
41
|
|
|
28
42
|
The sections below are conditional on `ARCHETYPE`. Execute only the section that matches.
|
|
29
43
|
|
|
@@ -592,12 +606,11 @@ indent_size = 2
|
|
|
592
606
|
|
|
593
607
|
Canonical implementation in [`_shared-template.md#parallel-sessions-rule`](_shared-template.md).
|
|
594
608
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
repo-aware maintenance prompt. See shared partial for full shell command. Issues #155, #633, #1060.
|
|
609
|
+
Execute the shared partial's `syncBootstrapRules` action. It supplies private
|
|
610
|
+
required basenames to `scripts/lib/rules-sync.mjs`, preserving its manifest,
|
|
611
|
+
pre-write validation and local-override checks. The partial appends actual newly
|
|
612
|
+
created rule paths, and creates `.claude/loop.md` only when missing. See the
|
|
613
|
+
shared partial for the executable shell command. Issues #155, #633, #1060.
|
|
601
614
|
|
|
602
615
|
Note: Runs before S99. S99 no longer fetches `parallel-sessions.md` from the baseline — that entry
|
|
603
616
|
was removed from the S99 manifest in #1060. The baseline copy carries no provenance header, so
|
|
@@ -611,8 +624,10 @@ Create the metrics directory and an empty learnings file so the `/evolve` skill
|
|
|
611
624
|
|
|
612
625
|
```bash
|
|
613
626
|
mkdir -p "$REPO_ROOT/.orchestrator/metrics"
|
|
614
|
-
[[ -
|
|
627
|
+
if [[ ! -e "$REPO_ROOT/.orchestrator/metrics/learnings.jsonl" && ! -L "$REPO_ROOT/.orchestrator/metrics/learnings.jsonl" ]]; then
|
|
615
628
|
: > "$REPO_ROOT/.orchestrator/metrics/learnings.jsonl"
|
|
629
|
+
BOOTSTRAP_FILES+=(.orchestrator/metrics/learnings.jsonl)
|
|
630
|
+
fi
|
|
616
631
|
```
|
|
617
632
|
|
|
618
633
|
**Idempotent.** Re-running bootstrap does not overwrite an existing file.
|
|
@@ -624,11 +639,13 @@ mkdir -p "$REPO_ROOT/.orchestrator/metrics"
|
|
|
624
639
|
|
|
625
640
|
Canonical implementation in [`_shared-template.md#baseline-fetch`](_shared-template.md).
|
|
626
641
|
|
|
627
|
-
|
|
642
|
+
PRIVATE: applies the selected local contract rule union without network access, preserving existing files and excluding every plugin-owned basename. An invalid contract aborts.
|
|
643
|
+
|
|
644
|
+
PUBLIC OPT-IN: only fires when `baseline-ref` is in Session Config, `GITLAB_TOKEN` is set, and
|
|
628
645
|
`scripts/lib/fetch-baseline.mjs` exists. Fetches `.claude/rules/*.md` from the baseline GitLab
|
|
629
646
|
project (default project 52) and writes `.claude/.baseline-fetch.lock`. Does NOT abort on failure.
|
|
630
|
-
The rule manifest
|
|
631
|
-
|
|
647
|
+
The private rule manifest comes from the selected contract. Every plugin-owned
|
|
648
|
+
basename is excluded from either delivery path. See the shared partial.
|
|
632
649
|
|
|
633
650
|
---
|
|
634
651
|
|
|
@@ -649,6 +666,8 @@ Write `.orchestrator/bootstrap.lock` **atomically** (mktemp + mv prevents a corr
|
|
|
649
666
|
process is interrupted mid-write):
|
|
650
667
|
|
|
651
668
|
```bash
|
|
669
|
+
_LOCK_CREATED=false
|
|
670
|
+
[[ -e "$REPO_ROOT/.orchestrator/bootstrap.lock" || -L "$REPO_ROOT/.orchestrator/bootstrap.lock" ]] || _LOCK_CREATED=true
|
|
652
671
|
_LOCK_TMP=$(mktemp "$REPO_ROOT/.orchestrator/bootstrap.lock.XXXXXX")
|
|
653
672
|
cat > "$_LOCK_TMP" << LOCK
|
|
654
673
|
# .orchestrator/bootstrap.lock
|
|
@@ -661,6 +680,7 @@ plugin-version: <session-orchestrator plugin version — read from $PLUGIN_ROOT/
|
|
|
661
680
|
bootstrapped-at: <current ISO 8601 UTC — same value as timestamp; distinct field for age-validation probe>
|
|
662
681
|
LOCK
|
|
663
682
|
mv "$_LOCK_TMP" "$REPO_ROOT/.orchestrator/bootstrap.lock"
|
|
683
|
+
if [[ "$_LOCK_CREATED" = true ]]; then BOOTSTRAP_FILES+=(.orchestrator/bootstrap.lock); fi
|
|
664
684
|
```
|
|
665
685
|
|
|
666
686
|
Set `source` using the same logic as fast-template Step 5:
|
|
@@ -673,8 +693,8 @@ Set `source` using the same logic as fast-template Step 5:
|
|
|
673
693
|
|
|
674
694
|
Canonical implementation in [`_shared-template.md#quality-gate-policy`](_shared-template.md).
|
|
675
695
|
|
|
676
|
-
Write `.orchestrator/policy/quality-gates.json`
|
|
677
|
-
|
|
696
|
+
Write `.orchestrator/policy/quality-gates.json` from exact private contract gates,
|
|
697
|
+
or package-manager defaults on the public path. Skip existing owner policy.
|
|
678
698
|
See shared partial for full shell command. Issue #183.
|
|
679
699
|
|
|
680
700
|
<!-- @include _shared-template.md#state-md-scaffold -->
|
|
@@ -682,8 +702,9 @@ See shared partial for full shell command. Issue #183.
|
|
|
682
702
|
|
|
683
703
|
Canonical implementation in [`_shared-template.md#state-md-scaffold`](_shared-template.md).
|
|
684
704
|
|
|
685
|
-
Scaffold `.claude/STATE.md`
|
|
686
|
-
|
|
705
|
+
Scaffold `.claude/STATE.md` (idempotent: skip if it already exists). <!-- path-check: example -->
|
|
706
|
+
Use `skills/bootstrap/STATE.md.template`.
|
|
707
|
+
On Codex CLI / Cursor IDE, substitute `.codex/` or `.cursor/` for `.claude/`.
|
|
687
708
|
See shared partial for full shell command. Issue #184.
|
|
688
709
|
|
|
689
710
|
<!-- @include _shared-template.md#agents-scaffold -->
|
|
@@ -701,15 +722,9 @@ Stage all created files and commit:
|
|
|
701
722
|
|
|
702
723
|
```bash
|
|
703
724
|
cd "$REPO_ROOT"
|
|
704
|
-
BOOTSTRAP_FILES=(
|
|
705
|
-
CLAUDE.md AGENTS.md .gitignore README.md .orchestrator/bootstrap.lock
|
|
706
|
-
.orchestrator/policy/quality-gates.json
|
|
707
|
-
package.json pyproject.toml tsconfig.json eslint.config.mjs .prettierrc
|
|
708
|
-
.editorconfig src/ tests/ .claude/
|
|
709
|
-
)
|
|
710
725
|
# Add only the files bootstrap created — no sweeping -u/-A to avoid catching pre-existing files
|
|
711
|
-
for _f in "${BOOTSTRAP_FILES[@]}"; do
|
|
712
|
-
[[ -
|
|
726
|
+
for _f in ${BOOTSTRAP_FILES[@]+"${BOOTSTRAP_FILES[@]}"}; do
|
|
727
|
+
[[ -f "$_f" && ! -L "$_f" ]] && git add -- "$_f"
|
|
713
728
|
done
|
|
714
729
|
git commit -m "chore: bootstrap (standard)"
|
|
715
730
|
```
|
|
@@ -142,6 +142,6 @@ fpRisk: low | medium | high
|
|
|
142
142
|
|
|
143
143
|
**Default Severity:** Per-rule (high for the absolute-ban tells, low for advisory quality nits). `fpRisk` is reported so triage can weight high-FP rules (`ai-purple-gradient`) more skeptically.
|
|
144
144
|
|
|
145
|
-
> **Precision boundary (honest):** this regex tier cannot resolve CSS cascade, so `side-stripe-border` flags any ≥2px side accent even when the element is unrounded —
|
|
145
|
+
> **Precision boundary (honest):** this regex tier cannot resolve CSS cascade, so `side-stripe-border` flags any ≥2px side accent even when the element is unrounded — `rules/opt-in-stack/frontend.md` bans those (>1px accent), but a cascade-aware detector would narrow further. The heavier static-HTML + browser tiers are deliberately omitted (cost ≫ value for a probe/hook). See `scripts/lib/frontend-detect/rules.mjs`.
|
|
146
146
|
|
|
147
147
|
---
|
|
@@ -8,7 +8,7 @@ Rules for mapping session scope to target audiences, content sources, and docume
|
|
|
8
8
|
|
|
9
9
|
| Audience | Target files (globs) | Typical update triggers |
|
|
10
10
|
|----------|----------------------|-------------------------|
|
|
11
|
-
| User | `README.md`, `docs/user/**/*.md`, `docs/getting-started.md`, `examples/**/*.md` | new CLI command, breaking API change, install flow change, new user-facing feature, changed example output |
|
|
11
|
+
| User | `README.md`, `docs/user/**/*.md`, `docs/getting-started.md`, `examples/**/*.md` | new CLI command, breaking API change, install flow change, new user-facing feature, changed example output <!-- path-check: example --> |
|
|
12
12
|
| Dev | `CLAUDE.md` (or `AGENTS.md` on Codex CLI), `docs/dev/**/*.md`, `docs/adr/**/*.md` | architecture decision, major refactor, new module/subsystem, test coverage change, dependency upgrade, ADR-worthy choice |
|
|
13
13
|
| Vault/Ops | `<vault>/01-projects/<slug>/context.md`, `<vault>/01-projects/<slug>/decisions.md`, `<vault>/01-projects/<slug>/people.md` | project status change, ownership transition, stack/infra decision, cross-project dependency, migration, archival event |
|
|
14
14
|
|
package/skills/evolve/SKILL.md
CHANGED
|
@@ -634,7 +634,7 @@ const result = await runDialecticDeriver({
|
|
|
634
634
|
```
|
|
635
635
|
|
|
636
636
|
### Step 6.4: Diff Output & Apply Gate
|
|
637
|
-
- If dry-run (default): present diff inline; write to `.orchestrator/dialectic-pending.md` (atomic tmp+rename); EXIT. Suggestion: "Re-run with `/evolve --dialectic --apply` to apply."
|
|
637
|
+
- If dry-run (default): present diff inline; write to `.orchestrator/dialectic-pending.md` (atomic tmp+rename); EXIT. Suggestion: "Re-run with `/evolve --dialectic --apply` to apply." <!-- path-check: example -->
|
|
638
638
|
- If `--apply`: call `mergePeerCard(existingBody, managedUpdates)` from `scripts/lib/peer-cards/merger.mjs` for each card target, then `writePeerCard(repoRoot, 'user', mergedUserCard)` and `writePeerCard(repoRoot, 'agent', mergedAgentCard)` from `scripts/lib/peer-cards/writer.mjs`. Update the `updated:` frontmatter.
|
|
639
639
|
- Report: `Dialectic-derived: M deltas to USER.md, N deltas to AGENT.md. Dry-run | Applied. Tokens: in=<X> out=<Y>.`
|
|
640
640
|
|
|
@@ -666,7 +666,7 @@ await recordDialecticRun({
|
|
|
666
666
|
- `status: 'budget-exceeded'` → emit `{status:'budget-exceeded', used:N, budget:M}`, do NOT truncate
|
|
667
667
|
- `status: 'would-empty-card'` → warn + require `--allow-emptying` flag
|
|
668
668
|
- `status: 'empty-input'` → exit clean with message "dialectic: skipped (no input)"
|
|
669
|
-
- subagent crash → log ⚠, exit cleanly (do NOT write to `.orchestrator/dialectic-pending.md`)
|
|
669
|
+
- subagent crash → log ⚠, exit cleanly (do NOT write to `.orchestrator/dialectic-pending.md`) <!-- path-check: example -->
|
|
670
670
|
|
|
671
671
|
**Telemetry (#1200, #1206) — emitted by `scripts/dialectic-deriver.mjs` for THREE of the five
|
|
672
672
|
outcomes.** `budget-exceeded`, `would-empty-card`, and `empty-input` are `runDialecticDeriver()`
|
|
@@ -111,7 +111,7 @@ done
|
|
|
111
111
|
**Taxonomy convention — `priority` REVERSED to scoped `::` (supersedes #727 for this one axis).**
|
|
112
112
|
|
|
113
113
|
- **`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:
|
|
114
|
-
- **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.
|
|
114
|
+
- **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"; the external team-organization audit `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. <!-- path-check: example -->
|
|
115
115
|
- **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.
|
|
116
116
|
- 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.
|
|
117
117
|
Producers were migrated FIRST (this change); the label-data migration follows separately, because migrating data before producers means the divergence returns within a day.
|
|
@@ -340,8 +340,8 @@ Bash calls when the current session contains no prior `Read` on a matching templ
|
|
|
340
340
|
**When this matters:** before you or a subagent opens an MR, PR, or issue via CLI, a
|
|
341
341
|
matching template must have been read in the current session:
|
|
342
342
|
|
|
343
|
-
- GitHub: `.github/
|
|
344
|
-
- GitLab: `.gitlab/merge_request_templates/Default.md` / `.gitlab/issue_templates/*`
|
|
343
|
+
- GitHub: `.github/pull_request_template.md` / `.github/ISSUE_TEMPLATE*`
|
|
344
|
+
- GitLab: `.gitlab/merge_request_templates/Default.md` / `.gitlab/issue_templates/*` <!-- path-check: example -->
|
|
345
345
|
|
|
346
346
|
Accepted template paths are configured in `.orchestrator/policy/templates-policy.json`
|
|
347
347
|
(versioned, operator-editable). Default behaviour:
|
package/skills/grill/SKILL.md
CHANGED
|
@@ -33,7 +33,7 @@ Read `soul.md` in this skill directory before anything else. It defines WHO you
|
|
|
33
33
|
Establish *what* you are grilling and ground yourself in the *code* before asking the user anything.
|
|
34
34
|
|
|
35
35
|
1. **Resolve the target.** Parse `$ARGUMENTS`:
|
|
36
|
-
- A file path (e.g. `docs/prd/2026-06-09-export.md`, `STATE.md`, a spec) → read it in full.
|
|
36
|
+
- A file path (e.g. `docs/prd/2026-06-09-export.md`, `STATE.md`, a spec) → read it in full. <!-- path-check: example -->
|
|
37
37
|
- A topic/slug or empty → grill the plan or idea already present in the current conversation. If there is no plan in context, ask the user — via AUQ — to state the plan in one or two sentences before continuing.
|
|
38
38
|
2. **Ground in the codebase.** Read the project's domain language if present (`CONTEXT.md`, `.orchestrator/steering/*.md`, relevant `docs/adr/*`), then Grep/Glob the areas the plan touches. Build a short mental model of what the code *actually* does today. This is what lets you run the code-contradiction tactic.
|
|
39
39
|
3. **State the target back.** In 1–2 plain-text sentences, summarize what you understand the plan to be and what you've grounded it against. This catches a wrong target before you waste a grill on it.
|
|
@@ -35,8 +35,8 @@ This skill accepts two optional flags. Default (no flag) runs the interactive 4-
|
|
|
35
35
|
|
|
36
36
|
| Flag | Behavior |
|
|
37
37
|
|---|---|
|
|
38
|
-
| `--dry-run` | Run Phases 1-3 read-only; instead of mutating MEMORY.md / topic files, write a complete-body MEMORY.md proposal (single fenced block — never a unified-diff) to `.orchestrator/pending-dream.md` (atomic). Exit 0. |
|
|
39
|
-
| `--apply-pending` | Read `.orchestrator/pending-dream.md`; refuse if older than 14 days (`stale`) or if MEMORY.md changed since the producing --dry-run (`stale-index`, #788); apply diff; delete pending file; print `auto-dream applied: -<X> lines, +<Y> entries`. Exit 0. |
|
|
38
|
+
| `--dry-run` | Run Phases 1-3 read-only; instead of mutating MEMORY.md / topic files, write a complete-body MEMORY.md proposal (single fenced block — never a unified-diff) to `.orchestrator/pending-dream.md` (atomic). Exit 0. <!-- path-check: example --> |
|
|
39
|
+
| `--apply-pending` | Read `.orchestrator/pending-dream.md`; refuse if older than 14 days (`stale`) or if MEMORY.md changed since the producing --dry-run (`stale-index`, #788); apply diff; delete pending file; print `auto-dream applied: -<X> lines, +<Y> entries`. Exit 0. <!-- path-check: example --> |
|
|
40
40
|
|
|
41
41
|
Flags are mutually exclusive — passing both is an error. Absence of both = legacy interactive mode (Phases 1-4 below).
|
|
42
42
|
|
package/skills/plan/mode-new.md
CHANGED
|
@@ -40,6 +40,15 @@ Agent({ subagent_type: "Explore", description: "Check ecosystem for conflicts",
|
|
|
40
40
|
5. **Core problem being solved** — Open-ended. Claude suggests structure if answer is vague.
|
|
41
41
|
6. **GitLab group** — Select the GitLab host explicitly, then discover available groups dynamically. Run `ls $BASELINE_PATH/templates/` for project types, and check for a groups config in `$BASELINE_PATH/config/` or run `glab api --hostname "$GITLAB_HOST" "groups?per_page=100&min_access_level=10"` to discover GitLab groups — read each entry's `full_path` field. (`glab` has no `group` subcommand at all — invoking one exits 1 with `Unknown command "group"`.) Present findings via AskUserQuestion.
|
|
42
42
|
|
|
43
|
+
### Optional private capability context — after Wave 1
|
|
44
|
+
|
|
45
|
+
Before Wave 2 research, apply [Private capability context](../_shared/private-capability-context.md)
|
|
46
|
+
only when the owner has explicitly supplied or authorized a local catalog lookup
|
|
47
|
+
for an explicitly private/internal planning audience. Use eligible findings to
|
|
48
|
+
inform the existing shared-patterns research and reuse alternatives; keep the
|
|
49
|
+
archetype research and questions below. With no authorized context, or with a
|
|
50
|
+
public/unknown audience, skip this optional step without a prompt or a lookup.
|
|
51
|
+
|
|
43
52
|
### Wave 2 — Technical Details (5 questions, dynamic per archetype)
|
|
44
53
|
|
|
45
54
|
**Pre-wave agents:**
|
|
@@ -238,7 +238,7 @@ Exit after printing. Do not proceed to Phase 4.
|
|
|
238
238
|
|
|
239
239
|
## Phase 4: Write Pending Sidecar (Normal Mode Only)
|
|
240
240
|
|
|
241
|
-
|
|
241
|
+
Create the runtime proposal sidecar `.orchestrator/metrics/reconcile-pending.md` as a human-readable <!-- path-check: example -->
|
|
242
242
|
record before presenting the AUQ. This sidecar is informational only — it lets the operator
|
|
243
243
|
see the full proposal set in an editor alongside the AUQ prompt.
|
|
244
244
|
|
|
@@ -280,8 +280,8 @@ Present to the user the **Session Summary**: Completed / Carried Over / Dropped
|
|
|
280
280
|
| `references/phase-3-documentation-updates.md` | Phase 3 full procedural body — final heartbeat (#590-3), 3.0 Defensive Cleanup, 3.1 SSOT files, 3.2/3.2a docs + handover, 3.3 rules freshness, 3.4/3.4a STATE.md write + snapshot cleanup, 3.45 Telemetry Flush, 3.5/3.5a/3.6.x memory + learnings + tail dispatcher, 3.7/3.7a/3.7b/3.7c/3.7d metrics, recommendations, durable commit, vault board, session-eval |
|
|
281
281
|
| `phase-3-2-docs-verification.md` | Phase 3.2 full procedural body — docs-tasks load, SESSION_START_REF, per-task loop, mode-gated report, Documentation Coverage block |
|
|
282
282
|
| `learning-patterns.md` | Phases 3.5a + 3.6 extraction heuristics, confidence updates, passive decay, and JSONL write procedure |
|
|
283
|
-
| `phase-3-6-tail.md` | Phase 3.6.x tail —
|
|
284
|
-
| `scripts/lib/session-end/phase-skip.mjs` | Phase 3.6.x tail skip-plan aggregator (#724) — `planTailPhases({repoRoot, config, sessionId, platform})` → `{plan, skippedReport}`; side-effect-free (reconcile/sweep via dry-run — no writes), never-throws (per-phase probe error fail-opens to `run: true`)
|
|
283
|
+
| `phase-3-6-tail.md` | Phase 3.6.x tail — detail procedures for the tail phases: 3.6.3 Memory-Proposals Collection (`collectProposals` + AUQ multiSelect + `promoteAndClear`, composing `writeApproved` + `clearProposalsJsonl` behind a mechanical write-before-clear guard, #828), **3.6.4 Expired-Learnings Sweep — MECHANICAL since 2026-09-09**: after `planTailPhases()`, call `runTailPhases({ repoRoot, plan })` from `scripts/lib/session-end/tail-runner.mjs` (delegating to `runExpiredSweep`) and report `result['3.6.4']` (`ran`, `scanned`, `archived`); the event `orchestrator.learnings.sweep_applied` is the proof it ran (Epic #723 B4), **3.6.5 Auto-Dream — RETIRED** and **3.6.7 Auto-Dialectic — RETIRED** (both replaced by the session-start `maintenance-due` probe, `checkMaintenanceDue` in `scripts/lib/maintenance-due-banner.mjs`; headings kept as two-line stubs because other docs cite them), 3.6.6 Skill-Applied Judge (#645 L3 — `runSkillJudge`, coordinator-writes), 3.6.8 Reconciliation Rule Proposals (#696 FA3 — `runReconcile` + AUQ + `writeApprovedRules`). Loaded on demand by the SKILL.md skip-plan dispatcher (#724) — only phases with `run: true` in the `planTailPhases()` plan execute |
|
|
284
|
+
| `scripts/lib/session-end/phase-skip.mjs` | Phase 3.6.x tail skip-plan aggregator (#724) — `planTailPhases({repoRoot, config, sessionId, platform})` → `{plan, skippedReport}`; side-effect-free (reconcile/sweep via dry-run — no writes), never-throws (per-phase probe error fail-opens to `run: true`). Since 2026-09-09 it plans FOUR phases, not six: the 3.6.5 (auto-dream) and 3.6.7 (auto-dialectic) deciders were removed with those phases' retirement. Its APPLY half for 3.6.4 is `scripts/lib/session-end/tail-runner.mjs` (`runTailPhases`, `runExpiredSweep`) — the planner fails OPEN, the runner fails CLOSED |
|
|
285
285
|
| `references/phase-3-documentation-updates.md` § 3.45 | Telemetry Flush (advisory, #844; MECHANICAL since #1138 — `hooks/on-session-end.mjs` calls `flush()` itself at the end of every teardown and emits an `orchestrator.telemetry.flush` breadcrumb, so this phase is the DESCRIPTION and the fallback, never the trigger; a coordinator that skips it changes nothing) — `flush()` from `scripts/lib/telemetry/sync.mjs` drains the host-local send-queue fire-and-forget; no config key (send-gate is `resolveConsent()` inside the module, fail-closed); skip when `persistence: false`; never-throw + ~3s-bounded, offline → bounded oldest-dropped queue, optional `Telemetry: sent/queued/gated` close-summary line, NEVER an error banner; runs late in the close after Phase 3.7 |
|
|
286
286
|
| `session-metrics-write.md` | Phase 3.7 JSONL append, vault-mirror invocation, durable narrative mirror (`mirrorNarrative`, #675), and behavior matrix |
|
|
287
287
|
| `phase-3-7a-recommendations.md` | Phase 3.7a full procedural body — computeV0Recommendation call, STATE.md field write, data source guarantee, error mode |
|
|
@@ -293,6 +293,7 @@ Present to the user the **Session Summary**: Completed / Carried Over / Dropped
|
|
|
293
293
|
| `references/phase-4a-worktree-cleanup.md` | Phase 4a full procedural body — auto-promoted-worktree detection (`detectAutoPromotedWorktree`, marker-keyed since #1069), clean-check, clean auto-remove path, dirty 3-option AUQ (`Behalten`/`Löschen`/`Manuell`), PSA-003 + #490 ordering rationale |
|
|
294
294
|
| `references/phase-4b-worktree-orphan-sweep.md` | Phase 4b full procedural body — `checkWorktreeOrphans()` read-only proposal set, the coordinator-rendered AUQ, opt-in `worktree-orphans.enabled` gate |
|
|
295
295
|
| `references/phase-5-issue-cleanup.md` | Phase 5 full procedural body — close resolved issues (`stripStatusLabels`, #308), Step 3 filing of the Phase 1.65 carry-list incl. the deferred `createSpiralCarryoverIssue` and `markOpenQuestionAnsweredOnDisk`, Step 3b `[Backlog-Sammel]` overflow, discovery-issue creation |
|
|
296
|
+
| `references/phase-5-issue-cleanup.md` § Step 3b.2 (issue-budget reconcile) | Phase 5 issue-budget cross-check — `reconcileIssueBudget({ repoRoot, record, sessionId, rawSessionId, config })` from `scripts/lib/issue-budget-reconcile.mjs` runs on the in-memory session record BEFORE it is appended to `sessions.jsonl`, `emitIssueBudgetReconciled` records `orchestrator.issue_budget.reconciled`, and `formatIssueBudgetReconcileWarn(result)` prints the verdict (`match` / `no-ledger` / `escaped` / `stale-record`) in the Final Report. Ordered AFTER the overflow drain (which resets `overflow[]`) and BEFORE `reapStaleBudgetFiles` (which must not remove the file being read) |
|
|
296
297
|
| `references/session-summary-template.md` | Phase 6 Final Report — the full Session Summary template (Completed / Carried Over / Dropped at Handover Gate / New Issues / Unresolved Review Findings / Metrics incl. Docs Health + Custom Phases / Next Session Recommendations) plus the Test-delta and Documentation-Coverage anchors |
|
|
297
298
|
|
|
298
299
|
## Anti-Patterns
|
|
@@ -57,7 +57,7 @@ The following mini-table mirrors `skills/docs-orchestrator/audience-mapping.md`
|
|
|
57
57
|
|
|
58
58
|
| Audience | Target file patterns |
|
|
59
59
|
|----------|----------------------|
|
|
60
|
-
| `user` | `README.md`, `docs/user/**/*.md`, `docs/getting-started.md`, `examples/**/*.md` |
|
|
60
|
+
| `user` | `README.md`, `docs/user/**/*.md`, `docs/getting-started.md`, `examples/**/*.md` <!-- path-check: example --> |
|
|
61
61
|
| `dev` | `CLAUDE.md` (or `AGENTS.md` on Codex CLI), `docs/dev/**/*.md`, `docs/adr/**/*.md` |
|
|
62
62
|
| `vault` | `<vault>/01-projects/<slug>/context.md`, `<vault>/01-projects/<slug>/decisions.md`, `<vault>/01-projects/<slug>/people.md` |
|
|
63
63
|
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
> - `memory.proposals.enabled` is `false` (default: `true`)
|
|
12
12
|
> - `.orchestrator/metrics/proposals.jsonl` does not exist OR contains zero entries
|
|
13
13
|
|
|
14
|
-
After learnings are written (Phase 3.6) and BEFORE
|
|
14
|
+
After learnings are written (Phase 3.6) and BEFORE the Skill-Applied Judge (Phase 3.6.6 — Phase 3.6.5 is retired), collect agent-proposed memory entries written during this session and present them to the operator via `AskUserQuestion` multiSelect. Approved entries flow to `learnings.jsonl` with `_provenance: agent-proposed@<wave-id>`. Rejected entries are archived to `.orchestrator/proposals.rejected.log`.
|
|
15
15
|
|
|
16
16
|
The proposals queue is populated mid-session by wave-executor agents calling `node scripts/memory-propose.mjs --type ... --subject ... --insight ... --evidence ... --confidence ...`. The CLI enforces:
|
|
17
17
|
- Quota per wave (default 5, configurable via `memory.proposals.quota-per-wave`)
|
|
@@ -138,40 +138,29 @@ The proposals queue is populated mid-session by wave-executor agents calling `no
|
|
|
138
138
|
|
|
139
139
|
> Best-effort, non-blocking. Skip silently if the sweep script errors or `.orchestrator/metrics/learnings.jsonl` is absent.
|
|
140
140
|
|
|
141
|
-
|
|
141
|
+
**MECHANICAL since 2026-09-09.** This phase is no longer a two-command prose recipe ("run `--json`, then `--apply --json` when `archived > 0`") — that recipe was the reason the apply path had ZERO session-end callers: measured across three consumer repos, 0 sweeps had ever been applied and 628 learnings were resident in the active stores. The dry-run decision already lives in `planTailPhases()`; the APPLY half now lives in `scripts/lib/session-end/tail-runner.mjs`.
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
After learnings are written (Phase 3.6) and `planTailPhases()` has produced its `plan` (see § "Phase 3.6.x Tail — Mechanical Skip-Plan" in `references/phase-3-documentation-updates.md`), call `runTailPhases` ONCE and read the `3.6.4` slot of its keyed result:
|
|
144
144
|
|
|
145
|
-
|
|
145
|
+
```javascript
|
|
146
|
+
import { runTailPhases } from '${PLUGIN_ROOT}/scripts/lib/session-end/tail-runner.mjs';
|
|
146
147
|
|
|
147
|
-
|
|
148
|
+
const tail = await runTailPhases({ repoRoot: process.cwd(), plan });
|
|
149
|
+
const sweep = tail['3.6.4'];
|
|
150
|
+
// { ran: true, scanned, archived, archivePath } | { ran: false, reason: 'plan-skip' | 'no-plan' | 'error', error? }
|
|
151
|
+
```
|
|
148
152
|
|
|
149
|
-
|
|
150
|
-
|
|
153
|
+
- `runTailPhases` delegates to `runExpiredSweep({ repoRoot, plan, now })` — the same module's single-phase entry point — and returns a KEYED shape so a caller keeps working when a second phase becomes mechanical. Today exactly one phase is: 3.6.3, 3.6.5–3.6.8 stay coordinator-executed because they are AUQ-gated or need a subagent dispatch a library function cannot make.
|
|
154
|
+
- **Never throws, fails CLOSED.** Any error yields `{ ran: false, reason: 'error' }` and the close proceeds. Stale-past-grace entries move into `.orchestrator/metrics/learnings-archive.jsonl` (append-only, never deleted).
|
|
155
|
+
- **Report** `sweep.ran`, `sweep.scanned` and `sweep.archived` in the Phase 6 Final Report, e.g. `expired-sweep: 12 archived of 640 scanned`. When `ran: false`, report the `reason` instead — a skipped sweep is a stated outcome, never silence.
|
|
156
|
+
- **The proof it ran is the event `orchestrator.learnings.sweep_applied`** in `.orchestrator/metrics/events.jsonl` (payload source `session-end-3.6.4`, which separates it from the standalone CLI). A close claiming a sweep with no such event did not sweep.
|
|
151
157
|
|
|
152
|
-
|
|
153
|
-
import { shouldDispatchAutoDream } from '${PLUGIN_ROOT}/scripts/lib/auto-dream.mjs';
|
|
154
|
-
import { resolveMemoryDir } from '${PLUGIN_ROOT}/scripts/lib/memory-paths.mjs';
|
|
155
|
-
const repoRoot = process.cwd();
|
|
156
|
-
const memoryDir = resolveMemoryDir(repoRoot);
|
|
157
|
-
const decision = await shouldDispatchAutoDream({
|
|
158
|
-
repoRoot,
|
|
159
|
-
memoryDir,
|
|
160
|
-
threshold: config['memory-cleanup-threshold'] ?? 5,
|
|
161
|
-
softLimit: config['memory-cleanup-soft-limit'] ?? 180,
|
|
162
|
-
});
|
|
163
|
-
```
|
|
164
|
-
3. If `decision.trigger === false`: log `auto-dream: not triggered (${decision.reason})` and continue. Emit no nudge.
|
|
165
|
-
4. If `decision.trigger === true`: **do not dispatch a subagent** — there is no `memory-cleanup` agent in `agents/`, so the historical `Agent({…})` dispatch pointed at the agent name `memory-cleanup` (a subagent type that was never built) and never fired (see #614). Instead, emit a manual-cadence nudge and continue:
|
|
158
|
+
The standalone `node scripts/sweep-expired-learnings.mjs --apply --json` CLI remains available for manual/out-of-session use; it is no longer the session-end path.
|
|
166
159
|
|
|
167
|
-
|
|
160
|
+
### 3.6.5 Auto-Dream Dispatch (#502, F2.2) — RETIRED
|
|
168
161
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
The pending-dream sidecar at `.orchestrator/pending-dream.md` is intentionally outside the vault tree — vault-mirror (Phase 3.7) must exclude it from its scope so the proposal survives the session close without being mirrored into 50-sessions/.
|
|
173
|
-
|
|
174
|
-
Cross-reference: PRD F2.2 acceptance criteria; `scripts/lib/auto-dream.mjs` API (`shouldDispatchAutoDream`, `readDreamSignals`, `writePendingDream`, `readPendingDream`, `applyPendingDream`).
|
|
162
|
+
> **RETIRED 2026-09-09.** The nudge is replaced by the session-start `maintenance-due` probe (`checkMaintenanceDue`, `scripts/lib/maintenance-due-banner.mjs`), whose `memory-cleanup` signal reuses the very same `shouldDispatchAutoDream` decision — a nudge emitted while the operator is closing down was read by nobody. Its decider is also gone from `planTailPhases()` in `scripts/lib/session-end/phase-skip.mjs`; the heading stays because other docs cite it.
|
|
163
|
+
> The housekeeping session runs `/memory-cleanup` itself (see `skills/session-start/SKILL.md` Phase 7 — the maintenance loop). `scripts/lib/auto-dream.mjs` (`shouldDispatchAutoDream`, `readDreamSignals`, `writePendingDream`, `readPendingDream`, `applyPendingDream`) stays in use: the probe reads it, and `/memory-cleanup --dry-run` / `--apply-pending` still write and consume `.orchestrator/pending-dream.md`. <!-- path-check: example -->
|
|
175
164
|
|
|
176
165
|
### 3.6.6 Skill-Applied Judge (#645, L3)
|
|
177
166
|
|
|
@@ -181,7 +170,7 @@ Cross-reference: PRD F2.2 acceptance criteria; `scripts/lib/auto-dream.mjs` API
|
|
|
181
170
|
>
|
|
182
171
|
> When skipped, log `skill-judge: disabled (skill-evolution.judge=false)` (or `persistence=false`) and return. **This is the disabled-path guarantee:** with the judge off, only L1 (`skill-invocations.jsonl`, written by the PreToolUse hook) and L2 (`scripts/lib/skill-health/join.mjs`) records exist — no judgment, no error, zero L3 code executes. Do NOT import `scripts/lib/skill-judge.mjs` on the disabled path.
|
|
183
172
|
|
|
184
|
-
After learnings are written (Phase 3.6)
|
|
173
|
+
After learnings are written (Phase 3.6), and when the judge is enabled, run a **bounded, read-only LLM-judge** over this session's selected skills to emit ADVISORY per-skill applied/completed judgments to `.orchestrator/metrics/skill-judgments.jsonl`.
|
|
185
174
|
|
|
186
175
|
**The #614 distinction (the whole point of L3's Design A):** unlike the 3.6.5 / 3.6.7 nudge-only paths — which cannot dispatch a live subagent because the target read-only agents (`memory-cleanup`, `dialectic-deriver`) cannot write their own sidecars — L3 performs a **LIVE read-only dispatch**. This is #614-safe because the read-only `skill-applied-judge` agent **RETURNS JSON** and the **COORDINATOR writes the sidecar**, not the agent. A read-only agent that returns judgments is allowed; a read-only agent that must write a file is the #614 trap.
|
|
187
176
|
|
|
@@ -238,41 +227,10 @@ After learnings are written (Phase 3.6) and the auto-dream decision is made (Pha
|
|
|
238
227
|
|
|
239
228
|
Cross-reference: PRD §A L3 acceptance criteria (#645, epic #643); `scripts/lib/skill-judge.mjs` API (`runSkillJudge`, `validateModel`, `estimateInputTokens`, `checkBudget`, `buildJudgePrompt`, `parseJudgeResponse`); `scripts/lib/skill-judgments-schema.mjs` (`appendSkillJudgment`, `readSkillJudgments`, `validateSkillJudgment`); agent `agents/skill-applied-judge.md`.
|
|
240
229
|
|
|
241
|
-
### 3.6.7 Auto-Dialectic Dispatch (#506, F2.5)
|
|
242
|
-
|
|
243
|
-
> Skip this phase if `dialectic.cadence: 0` (kill-switch per PRD F2.5 AC3). Also skip if `persistence` is `false` in Session Config.
|
|
244
|
-
|
|
245
|
-
After learnings are written (Phase 3.6) and the auto-dream decision is made (Phase 3.6.5), determine whether to emit a **manual-cadence nudge** to run `/evolve --dialectic` in the next session. The decision uses sessions-since-last-dialectic counted against `.orchestrator/dialectic-last-run`. There is no `evolve` agent in the registry, and the nearest one (`dialectic-deriver`) is `sandbox-tier: read-only` and cannot write the sidecar — so the historical auto-dialectic subagent dispatch never fired (see #614). On trigger, emit the nudge and advance `.orchestrator/dialectic-last-run`; the timestamp is updated only when the nudge is emitted (not on skip), so the reminder surfaces once per cadence window rather than every session. A manually-run `/evolve --dialectic --dry-run` writes the proposed diff to `.orchestrator/dialectic-pending.md`.
|
|
246
|
-
|
|
247
|
-
1. Read `dialectic.cadence` (default 5), `dialectic.model` (default haiku), `dialectic.budget-tokens` (default 8000) from `$CONFIG`.
|
|
248
|
-
|
|
249
|
-
2. Invoke `decideAndRecordAutoDialectic` from `scripts/lib/auto-dialectic.mjs`:
|
|
250
|
-
```javascript
|
|
251
|
-
import { decideAndRecordAutoDialectic } from '${PLUGIN_ROOT}/scripts/lib/auto-dialectic.mjs';
|
|
252
|
-
const decision = await decideAndRecordAutoDialectic({
|
|
253
|
-
repoRoot: process.cwd(),
|
|
254
|
-
cadence: config.dialectic?.cadence ?? 5,
|
|
255
|
-
});
|
|
256
|
-
```
|
|
257
|
-
Same return shape as `shouldDispatchAutoDialectic` (`{trigger, reason, signals}`) — `decideAndRecordAutoDialectic` calls it internally and additionally emits the mechanical `orchestrator.dialectic.nudge_decided` telemetry record on all four return paths (#1200 part c), so the nudge decision is observable without depending on this prose actually reaching step 5/7.
|
|
258
|
-
|
|
259
|
-
3. If `decision.trigger === false`: log `auto-dialectic: not triggered (${decision.reason})` and continue. Emit no nudge. Do NOT update `.orchestrator/dialectic-last-run`.
|
|
260
|
-
|
|
261
|
-
4. **AC4 precondition guard:** Even if cadence met, if `signals.sessionsSinceLast === 0 && signals.learningsSinceLast === 0`, skip with reason `no-new-input-since-last-run`. The Final Report (Phase 6) MUST include the literal string `dialectic: skipped (no new input since last run)`.
|
|
262
|
-
|
|
263
|
-
5. If `decision.trigger === true`: **do not dispatch a subagent** (see #614 — no `evolve` agent exists; `dialectic-deriver` is read-only and cannot write the sidecar). Instead, emit a manual-cadence nudge and continue:
|
|
264
|
-
|
|
265
|
-
`auto-dialectic: cadence reached (${decision.reason}) — run /evolve --dialectic --dry-run manually in the next session, review .orchestrator/dialectic-pending.md, then apply with /evolve --dialectic --apply.`
|
|
266
|
-
|
|
267
|
-
The `shouldDispatchAutoDialectic` decision helper and `scripts/lib/auto-dialectic.mjs` lib stay in use: they compute the cadence signal that drives this nudge.
|
|
268
|
-
|
|
269
|
-
6. When the nudge is emitted (cadence reached), update `.orchestrator/dialectic-last-run` via `writeDialecticLastRun({ repoRoot, isoTimestamp: new Date().toISOString() })` so the cadence counter advances and the nudge does not repeat every session. Atomic; failures non-fatal.
|
|
270
|
-
|
|
271
|
-
7. Record outcome (skipped / nudge-emitted) for Phase 6 Final Report: `auto-dialectic: manual /evolve --dialectic --dry-run recommended (cadence reached) — apply with /evolve --dialectic --apply next session`.
|
|
272
|
-
|
|
273
|
-
The `.orchestrator/dialectic-pending.md` sidecar is intentionally outside the vault tree — vault-mirror (Phase 3.7) MUST exclude it from its scope.
|
|
230
|
+
### 3.6.7 Auto-Dialectic Dispatch (#506, F2.5) — RETIRED
|
|
274
231
|
|
|
275
|
-
|
|
232
|
+
> **RETIRED 2026-09-09.** The nudge is replaced by the session-start `maintenance-due` probe (`checkMaintenanceDue`, `scripts/lib/maintenance-due-banner.mjs`), whose `dialectic` signal reads the side-effect-free `shouldDispatchAutoDialectic` — never a variant that advances the last-run stamp, which would consume the very signal it reports. Its decider is also gone from `planTailPhases()` in `scripts/lib/session-end/phase-skip.mjs`; the heading stays because other docs cite it.
|
|
233
|
+
> The housekeeping session runs `/evolve dialectic` itself (see `skills/session-start/SKILL.md` Phase 7 — the maintenance loop): dry-run first, review `.orchestrator/dialectic-pending.md`, then apply. `scripts/lib/auto-dialectic.mjs` (`shouldDispatchAutoDialectic`, `writeDialecticLastRun`) and the read-only `dialectic-deriver` agent stay in use on that manual path. The recording wrapper around that signal, and its `orchestrator.dialectic.nudge_decided` event, were removed in #1288 — nothing emits that event any more. <!-- path-check: example -->
|
|
276
234
|
|
|
277
235
|
> **Dialectic chain rationale** — design choices in the manual `/evolve --dialectic` chain (`/evolve → runDialecticDeriver → dispatchAgent → Agent`). Session-end no longer auto-dispatches this chain (see #614 — the `evolve` agent never existed); the rationale below applies when you run `/evolve --dialectic` manually:
|
|
278
236
|
> - **/evolve → subagent (not direct invoke):** the manual `/evolve --dialectic` skill spawns a subagent so the dialectic pass runs in a fresh context window — keeping the deriver's input-heavy payload (top-50 learnings + last-10 sessions + 2 peer cards + steering) out of the invoking coordinator's context, and letting the deriver run as Haiku while the coordinator stays Opus.
|
|
@@ -286,7 +244,7 @@ Cross-reference: PRD F2.5 acceptance criteria (#506); `scripts/lib/auto-dialecti
|
|
|
286
244
|
> - `reconcile.enabled` is `false` (default: `false` — opt-in; this is the silent no-op path for all repos that have not opted in)
|
|
287
245
|
> - `.orchestrator/metrics/learnings.jsonl` does not exist OR contains zero entries
|
|
288
246
|
|
|
289
|
-
After the
|
|
247
|
+
After the Skill-Applied Judge (Phase 3.6.6 — Phase 3.6.7 is retired), and when the reconcile engine is enabled, run the **reconciliation engine** to turn high-confidence learnings into conditional-rule proposals and present them to the operator via `AskUserQuestion` multiSelect. Approved proposals flow to `.claude/rules/` via `writeApprovedRules`. Rejected proposals are archived to `.orchestrator/reconcile.rejected.log`. The engine NEVER writes `.claude/rules/` itself — every write is operator-AUQ-gated (#693 FA2/FA3 brandmauer).
|
|
290
248
|
|
|
291
249
|
#### Coordinator-direct procedure
|
|
292
250
|
|
|
@@ -323,7 +281,7 @@ After the auto-dialectic nudge decision is made (Phase 3.6.7), and when the reco
|
|
|
323
281
|
|
|
324
282
|
3. If `surfaced.length === 0`: log `reconcile: 0 proposals above confidence floor (eligible=${summary.eligible}, rejected=${summary.rejected}, floor=${floor})` and continue. No AUQ, no sidecar write.
|
|
325
283
|
|
|
326
|
-
4. **Write the human-readable proposal sidecar** `.orchestrator/metrics/reconcile-pending.md` so the operator can review raw content outside the AUQ:
|
|
284
|
+
4. **Write the human-readable proposal sidecar** `.orchestrator/metrics/reconcile-pending.md` so the operator can review raw content outside the AUQ: <!-- path-check: example -->
|
|
327
285
|
|
|
328
286
|
```
|
|
329
287
|
# Reconciliation Rule Proposals — <ISO timestamp>
|
|
@@ -76,7 +76,7 @@ try {
|
|
|
76
76
|
|
|
77
77
|
## Phase 3.7b: Durable-Commit Session Telemetry (#490 AC2)
|
|
78
78
|
|
|
79
|
-
> **Ordering:** Runs AFTER Phase 3.7a (Recommendation fields just-written to STATE.md) and BEFORE Phase 3.4 (`status: completed`). The canonical runtime order is `… → 3.6.
|
|
79
|
+
> **Ordering:** Runs AFTER Phase 3.7a (Recommendation fields just-written to STATE.md) and BEFORE Phase 3.4 (`status: completed`). The canonical runtime order is `… → 3.6.6 → 3.6.8 → 3.7 → 3.7a → 3.7b → 3.7c → 3.7d → 3.4` (3.6.5 Auto-Dream and 3.6.7 Auto-Dialectic were RETIRED 2026-09-09 — see `phase-3-6-tail.md`). Both session-end-owned files (`sessions.jsonl` from Phase 3.7, `STATE.md` from Phase 3.7a) have already been written to disk; this step only declares them as the durable-commit set.
|
|
80
80
|
|
|
81
81
|
> **Ownership:** session-end commits ONLY the two files it owns — `.orchestrator/metrics/sessions.jsonl` and `<state-dir>/STATE.md`. `.orchestrator/metrics/autopilot.jsonl` is NOT session-end's responsibility: `scripts/lib/autopilot/loop.mjs` commits that file in the autopilot loop (the core `loop.mjs` wiring shipped in #490 Wave-2). Do not add autopilot.jsonl to the files array here.
|
|
82
82
|
|
|
@@ -95,6 +95,6 @@ await withDurableCommit(
|
|
|
95
95
|
);
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
-
- Use the platform-resolved `<state-dir>/STATE.md` path (e.g. `~/.claude/STATE.md` on Claude Code) — NOT a hardcoded `.claude/STATE.md`.
|
|
98
|
+
- Use the platform-resolved `<state-dir>/STATE.md` path (e.g. `~/.claude/STATE.md` on Claude Code) — NOT a hardcoded `.claude/STATE.md`. <!-- path-check: example -->
|
|
99
99
|
- The `files` array is staged individually by `durableCommit` (PSA-004: never `git add .`/`-A`); the existing `SAFE_BRANCH_RE` branch-name allowlist + cwd-confinement guards in `durable-telemetry.mjs` apply unchanged.
|
|
100
100
|
- `enabled: false` short-circuits before any git command runs, so the local-execution path performs zero VCS mutation — Phase 4 (`git add` + commit) remains the single staging point for local closes.
|