session-orchestrator 4.0.1 → 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.
Files changed (145) hide show
  1. package/.agents/skills/session-plan/SKILL.md +1 -1
  2. package/.claude-plugin/marketplace.json +1 -1
  3. package/.claude-plugin/plugin.json +1 -1
  4. package/.codex-plugin/plugin.json +1 -1
  5. package/.codex-plugin/skills/session-plan/SKILL.md +1 -1
  6. package/.cursor/skills/session-plan/SKILL.md +1 -1
  7. package/.cursor-plugin/plugin.json +1 -1
  8. package/CHANGELOG.md +57 -0
  9. package/README.md +55 -51
  10. package/agents/ux-evaluator.md +1 -1
  11. package/commands/close.md +3 -3
  12. package/commands/go.md +2 -0
  13. package/commands/memory-cleanup.md +4 -3
  14. package/commands/persona-panel.md +1 -1
  15. package/commands/release.md +4 -4
  16. package/commands/session.md +3 -2
  17. package/docs/README.md +4 -4
  18. package/docs/USER-GUIDE.md +115 -48
  19. package/docs/agent-authoring.md +2 -2
  20. package/docs/baseline.md +55 -1
  21. package/docs/ci-setup.md +1 -1
  22. package/docs/codex-setup.md +1 -0
  23. package/docs/components.md +2 -2
  24. package/docs/cursor-setup.md +1 -0
  25. package/docs/events-schema.md +4 -1
  26. package/docs/instruction-delivery.md +1 -1
  27. package/docs/memory-proposal-flow.md +3 -3
  28. package/docs/migration-v4.md +2 -2
  29. package/docs/owner-config-schema.md +74 -90
  30. package/docs/persona-panel.md +4 -4
  31. package/docs/pi-setup.md +1 -0
  32. package/docs/rule-authoring.md +13 -6
  33. package/docs/scope-collision-guard.md +2 -0
  34. package/docs/session-config-reference.md +55 -22
  35. package/docs/session-config-template.md +9 -5
  36. package/docs/vault-docs-architecture.md +4 -2
  37. package/hooks/_lib/hook-import-set.json +28 -3
  38. package/hooks/_lib/vcs-create-matcher.mjs +214 -16
  39. package/hooks/hooks-codex.json +1 -1
  40. package/hooks/hooks.json +1 -1
  41. package/hooks/pre-bash-issue-budget.mjs +123 -26
  42. package/hooks/subagent-telemetry.mjs +106 -20
  43. package/package.json +4 -4
  44. package/scripts/baseline-archetypes.mjs +28 -0
  45. package/scripts/ci/assert-coverage-green.mjs +100 -0
  46. package/scripts/lib/auto-dialectic.mjs +0 -68
  47. package/scripts/lib/baseline-archetypes.mjs +439 -0
  48. package/scripts/lib/build-live-signals.mjs +5 -6
  49. package/scripts/lib/config/issue-budget.mjs +68 -8
  50. package/scripts/lib/config/private-config-dir.mjs +3 -2
  51. package/scripts/lib/config/remote-hosts.mjs +2 -2
  52. package/scripts/lib/config-schema.mjs +79 -0
  53. package/scripts/lib/events.mjs +3 -3
  54. package/scripts/lib/file-lock.mjs +47 -5
  55. package/scripts/lib/issue-budget-reconcile.mjs +392 -0
  56. package/scripts/lib/issue-budget.mjs +76 -3
  57. package/scripts/lib/learnings/evolve-telemetry.mjs +1 -2
  58. package/scripts/lib/maintenance-due-banner.mjs +440 -0
  59. package/scripts/lib/owner-config.example.yaml +29 -46
  60. package/scripts/lib/owner-yaml.mjs +14 -13
  61. package/scripts/lib/project-hygiene.mjs +182 -6
  62. package/scripts/lib/quality-gate.mjs +13 -6
  63. package/scripts/lib/resource-probe/evaluate.mjs +19 -21
  64. package/scripts/lib/rules-sync.mjs +34 -4
  65. package/scripts/lib/session-close-backfill.mjs +182 -40
  66. package/scripts/lib/session-end/phase-skip.mjs +85 -86
  67. package/scripts/lib/session-end/tail-runner.mjs +178 -0
  68. package/scripts/lib/session-identity/own-session.mjs +24 -13
  69. package/scripts/lib/session-schema/constants.mjs +6 -0
  70. package/scripts/lib/session-schema/validator.mjs +20 -0
  71. package/scripts/lib/session-shape.mjs +558 -0
  72. package/scripts/lib/session-start-probes.mjs +10 -3
  73. package/scripts/lib/session-token-rollup.mjs +95 -10
  74. package/scripts/lib/state-md/frontmatter-mutators.mjs +22 -34
  75. package/scripts/lib/state-md.mjs +1 -0
  76. package/scripts/lib/subagents-schema.mjs +77 -9
  77. package/scripts/lib/telemetry/pricing.mjs +197 -0
  78. package/scripts/lib/telemetry/sync.mjs +50 -1
  79. package/scripts/lib/validate/check-owner-leakage.mjs +17 -8
  80. package/scripts/lib/validate/check-skill-script-paths.mjs +33 -10
  81. package/scripts/lib/validate/check-unwired-features.mjs +8 -7
  82. package/scripts/lib/vault-mirror/process.mjs +2 -1
  83. package/scripts/lib/vault-mirror/render-sessions.mjs +8 -1
  84. package/scripts/lib/vault-status/narrative-mirror.mjs +4 -4
  85. package/scripts/lib/wave-resource-gate.mjs +23 -27
  86. package/scripts/lib/wave-sizing.mjs +10 -3
  87. package/scripts/materialize-wave-scope.mjs +68 -14
  88. package/scripts/print-applicable-rules.mjs +7 -6
  89. package/scripts/print-learnings-index.mjs +3 -2
  90. package/scripts/release.mjs +32 -11
  91. package/scripts/session-shape.mjs +266 -0
  92. package/skills/_shared/config-reading.md +15 -9
  93. package/skills/_shared/private-capability-context.md +89 -0
  94. package/skills/bootstrap/SKILL.md +61 -13
  95. package/skills/bootstrap/_shared-template.md +99 -14
  96. package/skills/bootstrap/deep-template.md +36 -26
  97. package/skills/bootstrap/fast-template.md +44 -8
  98. package/skills/bootstrap/intensity-heuristic.md +10 -4
  99. package/skills/bootstrap/private-contract.md +119 -0
  100. package/skills/bootstrap/public-fallback.md +30 -18
  101. package/skills/bootstrap/standard-template.md +39 -24
  102. package/skills/discovery/probes-ui.md +1 -1
  103. package/skills/docs-orchestrator/audience-mapping.md +1 -1
  104. package/skills/evolve/SKILL.md +2 -2
  105. package/skills/gitlab-ops/SKILL.md +3 -3
  106. package/skills/grill/SKILL.md +1 -1
  107. package/skills/memory-cleanup/SKILL.md +2 -2
  108. package/skills/plan/mode-new.md +9 -0
  109. package/skills/reconcile/SKILL.md +1 -1
  110. package/skills/session-end/SKILL.md +3 -2
  111. package/skills/session-end/phase-3-2-docs-verification.md +1 -1
  112. package/skills/session-end/phase-3-6-tail.md +23 -65
  113. package/skills/session-end/phase-3-7a-recommendations.md +2 -2
  114. package/skills/session-end/references/phase-3-documentation-updates.md +8 -6
  115. package/skills/session-end/references/phase-5-issue-cleanup.md +26 -0
  116. package/skills/session-end/session-metrics-write.md +31 -12
  117. package/skills/session-plan/SKILL.md +56 -48
  118. package/skills/session-plan/wave-template.md +8 -15
  119. package/skills/session-start/SKILL.md +18 -2
  120. package/skills/session-start/phase-2-5-docs-planning.md +1 -1
  121. package/skills/session-start/phase-8-5-express-path.md +12 -9
  122. package/skills/session-start/references/phase-1-5-session-continuity.md +2 -0
  123. package/skills/session-start/references/phase-4-ssot-environment-check.md +21 -5
  124. package/skills/session-start/references/phase-6-7-memory-banner-telemetry-consent.md +3 -1
  125. package/skills/test-runner/rubric-v1.md +2 -2
  126. package/skills/wave-executor/SKILL.md +42 -12
  127. package/skills/wave-executor/circuit-breaker.md +3 -1
  128. package/skills/wave-executor/references/wave-loop-dispatch.md +4 -2
  129. package/skills/wave-executor/references/wave-loop-review.md +1 -1
  130. package/skills/wave-executor/references/wave-loop-scope-manifest.md +6 -2
  131. package/templates/nextjs-minimal/package.json +1 -1
  132. package/templates/node-minimal/package.json +1 -1
  133. package/scripts/lib/multi-provider-build/providers.mjs +0 -64
  134. package/scripts/lib/multi-provider-build/templating.mjs +0 -130
  135. package/scripts/lib/owner-config/coerce.mjs +0 -29
  136. package/scripts/lib/owner-config/constants.mjs +0 -21
  137. package/scripts/lib/owner-config/defaults.mjs +0 -50
  138. package/scripts/lib/owner-config/error.mjs +0 -19
  139. package/scripts/lib/owner-config/index.mjs +0 -13
  140. package/scripts/lib/owner-config/merge.mjs +0 -52
  141. package/scripts/lib/owner-config/validate.mjs +0 -259
  142. package/scripts/lib/owner-config-loader.mjs +0 -170
  143. package/scripts/lib/owner-config.mjs +0 -28
  144. package/scripts/lib/soul-resolve.mjs +0 -130
  145. package/scripts/lib/vault-mirror/render.mjs +0 -8
@@ -8,7 +8,7 @@
8
8
  After executing this algorithm, report:
9
9
 
10
10
  - `RECOMMENDED_TIER`: `fast` | `standard` | `deep`
11
- - `RECOMMENDED_ARCHETYPE`: `static-html` | `node-minimal` | `nextjs-minimal` | `python-uv` | `null`
11
+ - `RECOMMENDED_ARCHETYPE`: a validated private contract ID, one of the public IDs, or `null`
12
12
  - `HEURISTIC_REASON`: one sentence explaining the recommendation (shown to user)
13
13
  - `ARCHETYPE_CONFIDENCE`: `high` | `low` (used to decide whether to ask the optional second question)
14
14
 
@@ -54,7 +54,13 @@ Examples:
54
54
 
55
55
  **Fast tier:** Always `RECOMMENDED_ARCHETYPE = null`, `ARCHETYPE_CONFIDENCE = high`. No stack needed — skip to output.
56
56
 
57
- **Private path (baseline configured):** Always `RECOMMENDED_ARCHETYPE = null` at this stage. The baseline's own archetype selector is used during Standard/Deep scaffolding. Set `ARCHETYPE_CONFIDENCE = high`.
57
+ **Private path (valid configured contract):** Use `BOOTSTRAP_CONTRACT.selected.id`
58
+ from Phase 0.5 and set `ARCHETYPE_CONFIDENCE = high` when markers match. An
59
+ explicit user ID must pass the reader's `--archetype` lookup and takes priority.
60
+ If no markers match, set `RECOMMENDED_ARCHETYPE = null` and
61
+ `ARCHETYPE_CONFIDENCE = low`; select from the returned ordered catalog using
62
+ `private-contract.md` before Standard/Deep scaffolding. Detection follows the
63
+ exported signal predicates and priority; no public default applies here.
58
64
 
59
65
  **Public path + Standard or Deep:** Scan the prompt for these signals:
60
66
 
@@ -66,7 +72,7 @@ Examples:
66
72
  | python, py, data, daten, ml, machine learning, api (python context), django, fastapi, flask, pandas, numpy | `python-uv` | high |
67
73
  | Ambiguous — prompt mentions multiple stacks, no clear frontend/backend split, or is too vague (e.g., "Ich brauche ein Projekt", "neues Repo", "etwas bauen") | `node-minimal` (safe default) | `low` |
68
74
 
69
- When `ARCHETYPE_CONFIDENCE = low`, the bootstrap skill will ask a second `AskUserQuestion` to confirm the archetype. `node-minimal` is the pre-selected default for that question.
75
+ On the public path, when `ARCHETYPE_CONFIDENCE = low`, the bootstrap skill will ask a second `AskUserQuestion` to confirm the archetype. `node-minimal` is the pre-selected default for that question.
70
76
 
71
77
  ## Step 5: Output
72
78
 
@@ -74,7 +80,7 @@ Return all four values to `SKILL.md` Phase 1:
74
80
 
75
81
  ```
76
82
  RECOMMENDED_TIER: fast | standard | deep
77
- RECOMMENDED_ARCHETYPE: static-html | node-minimal | nextjs-minimal | python-uv | null
83
+ RECOMMENDED_ARCHETYPE: <validated private ID> | static-html | node-minimal | nextjs-minimal | python-uv | null
78
84
  HEURISTIC_REASON: <one sentence>
79
85
  ARCHETYPE_CONFIDENCE: high | low
80
86
  ```
@@ -0,0 +1,119 @@
1
+ # Configured Baseline Bootstrap
2
+
3
+ Use this flow only after `public-fallback.md` returned `PATH_TYPE = private`.
4
+ The configured local baseline owns the archetype catalog. The plugin consumes
5
+ its validated, reduced export; it carries no private archetype table.
6
+
7
+ ## Select
8
+
9
+ For Standard/Deep, use the `selected.id` returned by Phase 0.5 when repository
10
+ markers match. An explicit owner-supplied ID takes precedence: validate it with
11
+ `--archetype` before accepting it. A user description can help present choices,
12
+ but cannot invent a catalog ID. When `selected` is null, present the returned
13
+ `archetypes` in `order`, showing their runtime, package manager, UI/API and deploy
14
+ metadata. Ask for the needed selection; paginate if the UI limits option count.
15
+ Do not substitute a public default for missing evidence or an invalid choice.
16
+
17
+ Once selected, set `CONFIRMED_ARCHETYPE` and refresh the contract:
18
+
19
+ ```bash
20
+ BOOTSTRAP_CONTRACT=$(node "$PLUGIN_ROOT/scripts/baseline-archetypes.mjs" \
21
+ --repo "$REPO_ROOT" --archetype "$CONFIRMED_ARCHETYPE") || exit 2
22
+ export BOOTSTRAP_CONTRACT
23
+ ```
24
+
25
+ `status: error` aborts before scaffolding. Its reason is safe to report; do not
26
+ print baseline paths, raw producer diagnostics, or private catalog files.
27
+ `insufficient-evidence` is a selection state, not permission to use `node-minimal`.
28
+ Fast tier has no archetype; use the plugin's minimal instruction-file flow and
29
+ skip this file's scaffold/rules actions until upgrading to Standard/Deep.
30
+
31
+ ## Scaffold
32
+
33
+ Execute this before Standard inherits the Fast steps. It runs only the local
34
+ baseline's `render_archetype_dir`, `render_shared_and_substitute`, and
35
+ `render_archetype_metadata` functions in temporary staging. It excludes all
36
+ staged rules; S99 below and `rules-sync` own rule delivery. It never invokes the
37
+ interactive setup script, package installation, Git, or a remote service.
38
+
39
+ ```bash
40
+ export PLUGIN_ROOT REPO_ROOT CONFIRMED_ARCHETYPE REPO_NAME
41
+ SCAFFOLD_RESULT=$(node --input-type=module <<'NODE'
42
+ import { pathToFileURL } from 'node:url';
43
+ const { scaffoldBaselineArchetype } = await import(pathToFileURL(`${process.env.PLUGIN_ROOT}/scripts/lib/baseline-archetypes.mjs`));
44
+ const result = await scaffoldBaselineArchetype({
45
+ repoRoot: process.env.REPO_ROOT,
46
+ archetype: process.env.CONFIRMED_ARCHETYPE,
47
+ projectName: process.env.REPO_NAME,
48
+ });
49
+ process.stdout.write(`${JSON.stringify(result)}\n`);
50
+ if (result.status === 'error') process.exitCode = 2;
51
+ NODE
52
+ ) || exit 2
53
+ printf '%s\n' "$SCAFFOLD_RESULT"
54
+ while IFS= read -r _file; do BOOTSTRAP_FILES+=("$_file"); done \
55
+ < <(printf '%s\n' "$SCAFFOLD_RESULT" | jq -r '.created[]')
56
+ ```
57
+
58
+ The report lists relative `created` and `preserved` files plus `unavailableGates`. Add only `created`
59
+ files to `BOOTSTRAP_FILES`; an existing file is preserved for owner review.
60
+ All sources and destinations are checked for symlinks before the first copy.
61
+ The renderer's commands are fixed function calls; exported `commands` and
62
+ `qualityGates[].command` remain data throughout lookup and staging.
63
+
64
+ Continue Fast's common steps, preserving the rendered instruction files,
65
+ README, manifests and configuration. Then skip Standard's four public stack
66
+ sections and continue at Step 3a, S99 and the lock/quality-policy steps.
67
+
68
+ ## Expectations
69
+
70
+ Use `selected.runtimes`, `packageManagers`, `ui`, `api`, `deploy`, `commands`,
71
+ `qualityGates`, `ci`, and `browserAutomation` as the scaffold expectations.
72
+ Keep rendered command documentation and CI. Staging normalizes new Session
73
+ Config `test-command`, `typecheck-command`, and `lint-command` from exactly
74
+ matching `qualityGates[].id` values (`test`, `typecheck`, `lint`). An absent gate
75
+ gets the literal failing command `false` and an unavailable explanation, so a
76
+ later generic gate runner cannot report an unsupported check as passing. No
77
+ other ID is silently relabeled. Existing owner instruction files are preserved.
78
+
79
+ For private verification, enumerate the selected `qualityGates` and report each
80
+ declared result. Separately report absent test/typecheck/lint slots as
81
+ unavailable; do not execute their `false` placeholders as if they were declared
82
+ checks, or claim that all three generic checks passed. Command execution is a
83
+ later explicit bootstrap step, separate from lookup and staging. Step 6.5 writes
84
+ the same exact mapping to a new quality policy, whose commands take precedence
85
+ at runtime. Existing owner policy is preserved; report any divergence for review.
86
+ The generic quality runner is unchanged.
87
+
88
+ Deep D1 preserves the baseline CI and its `ci.profile`. If `ci.required` is
89
+ false, do not create a public Node CI pipeline. If true and the baseline did
90
+ not render CI, staging fails. VCS mismatch or a required translation needs an
91
+ explicit owner choice; do not silently replace the canonical CI with a public
92
+ template. The remaining Deep governance steps apply normally.
93
+
94
+ ## Rules
95
+
96
+ S99 re-reads the selected contract after rendering, so dependency-conditional
97
+ targets include the new package manifest. `ruleTargets` is the exported union;
98
+ `pluginRuleTargets` is its intersection with all basenames in `rules/_index.md`.
99
+ Only `baselineRules` may be copied from the local baseline. Every source is a
100
+ validated relative file under `.claude/rules/` or
101
+ `templates/shared/.claude/rules/`, and every target belongs to that union.
102
+ Existing rules are preserved. Plugin rule basenames, including
103
+ `parallel-sessions.md`, are written only by `rules-sync.mjs`. Step 3a invokes
104
+ `syncBootstrapRules`, which reloads the contract and passes `pluginRuleTargets`
105
+ as the writer's validated required basenames. This delivers private requirements
106
+ even when plugin scope tags do not name that archetype. The same action backs
107
+ later `/bootstrap --sync-rules`, resolving the explicit ID, then the lock ID,
108
+ then repository markers. Public/default rule selection remains unchanged.
109
+ Later sync of a valid Fast/null lock without stack markers also uses ordinary
110
+ plugin rules; a configured contract must still validate before that refresh.
111
+
112
+ ## Created files
113
+
114
+ Keep one `BOOTSTRAP_FILES` array throughout inherited Fast/Standard/Deep steps.
115
+ Each writer appends only relative files it actually creates; do not replace the
116
+ array with a stack-specific list. Existing owner files and directories are never
117
+ added merely because they exist. A repeated writer reporting `created: []`
118
+ leaves accumulated paths intact. New governance files are appended individually
119
+ at creation, and commit steps consume this accumulated list without broad globs.
@@ -5,32 +5,38 @@
5
5
 
6
6
  ## Step 1: Detect PATH_TYPE (Silent — No User Interaction)
7
7
 
8
- Read `plan-baseline-path` from Session Config in `CLAUDE.md` (or `AGENTS.md` on Codex):
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
- BASELINE_PATH=$(grep -m1 "^plan-baseline-path:" "$REPO_ROOT/CLAUDE.md" 2>/dev/null | awk '{print $2}')
12
- # Expand leading ~ to $HOME so paths like ~/Projects/projects-baseline work correctly
13
- BASELINE_PATH="${BASELINE_PATH/#\~/$HOME}"
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
- Decision logic (evaluated in order — first match wins):
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
- | Condition | PATH_TYPE |
19
- |-----------|-----------|
20
- | `plan-baseline-path` key is absent in Session Config | `public` |
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
- When `PATH_TYPE = private`, the baseline templates are used directly. No new logic is needed here — the existing tier-template flow (`fast-template.md`, `standard-template.md`, `deep-template.md`) already calls `$BASELINE_PATH` scripts for CLAUDE.md generation and archetype file sourcing. Continue with the calling template file's steps unchanged.
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
- Valid values: `static-html` | `node-minimal` | `nextjs-minimal` | `python-uv`
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
- If `ARCHETYPE` is `null` or unset at this point, default to `node-minimal`.
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
- Run `node "$PLUGIN_ROOT/scripts/lib/rules-sync.mjs" --repo-root "$REPO_ROOT"` — it vendors every
596
- rule registered in `rules/_index.md` (idempotent: missing→create, identical→skip, differs→overwrite),
597
- and it is the only writer that applies the pre-write validator, the basename-collision guard and the
598
- copy-on-write branch that preserves repo-private rules. The shared partial also runs
599
- `cp "$PLUGIN_ROOT/templates/_shared/loop.md" "$REPO_ROOT/.claude/loop.md"` so bare `/loop` gets a
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
- [[ -f "$REPO_ROOT/.orchestrator/metrics/learnings.jsonl" ]] || \
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
- OPT-IN: only fires when `baseline-ref` is in Session Config, `GITLAB_TOKEN` is set, and
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 includes `owner-persona.md` (alongside `parallel-sessions.md`, `development.md`,
631
- and the rest of the always-on rules). See shared partial for full implementation.
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` with package-manager-detected defaults (idempotent:
677
- skip if file already exists). Uses `scripts/lib/package-manager.mjs`; falls back to npm defaults.
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` from `skills/bootstrap/STATE.md.template` (idempotent: skip if
686
- already exists). On Codex CLI / Cursor IDE, substitute `.codex/` or `.cursor/` for `.claude/`.
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
- [[ -e "$_f" ]] && git add -- "$_f"
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 — `.claude/rules/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`.
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
 
@@ -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/PULL_REQUEST_TEMPLATE.md` / `.github/ISSUE_TEMPLATE*`
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:
@@ -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
 
@@ -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
- Write the proposals to `.orchestrator/metrics/reconcile-pending.md` as a human-readable
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 — full unabridged detail procedures for all six 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 (Epic #723 B4), 3.6.5 Auto-Dream nudge (`shouldDispatchAutoDream`, #614), 3.6.6 Skill-Applied Judge (#645 L3 — `runSkillJudge`, coordinator-writes), 3.6.7 Auto-Dialectic nudge (`shouldDispatchAutoDialectic`, #614), 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`); wraps the six existing signal helpers with config gates first, then input detection |
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