session-orchestrator 4.1.0 → 5.0.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/.agents/skills/session-start/SKILL.md +1 -1
- package/.agents/skills/ux-grill/SKILL.md +22 -0
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +3 -2
- package/.codex-plugin/plugin.json +1 -1
- package/.codex-plugin/skills/session-plan/SKILL.md +1 -1
- package/.codex-plugin/skills/session-start/SKILL.md +1 -1
- package/.codex-plugin/skills/ux-grill/SKILL.md +21 -0
- package/.codex-plugin/skills/ux-grill/agents/openai.yaml +5 -0
- package/.cursor/commands/ux-grill.md +14 -0
- package/.cursor/skills/session-plan/SKILL.md +1 -1
- package/.cursor/skills/session-start/SKILL.md +1 -1
- package/.cursor/skills/ux-grill/SKILL.md +13 -0
- package/.cursor-plugin/plugin.json +1 -1
- package/AGENTS.md +2 -1
- package/CHANGELOG.md +128 -1
- package/README.md +98 -86
- package/agents/dialectic-deriver.md +11 -0
- 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/commands/ux-grill.md +51 -0
- package/docs/README.md +4 -4
- package/docs/USER-GUIDE.md +117 -50
- 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 +9 -0
- package/docs/components.md +9 -9
- package/docs/cursor-setup.md +1 -0
- package/docs/events-schema.md +13 -6
- package/docs/github-mirror-protection.md +61 -20
- package/docs/instruction-delivery.md +1 -1
- package/docs/memory-proposal-flow.md +3 -3
- package/docs/migration-v4.md +2 -2
- package/docs/migration-v5.md +62 -0
- 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 +16 -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 +70 -3
- package/hooks/_lib/lock-bootstrap.mjs +84 -1
- package/hooks/_lib/vcs-create-matcher.mjs +401 -16
- package/hooks/enforce-scope.mjs +201 -0
- package/hooks/hooks-codex.json +1 -1
- package/hooks/hooks-cursor.json +5 -0
- package/hooks/hooks.json +7 -2
- package/hooks/on-session-start.mjs +171 -49
- package/hooks/post-bash-issue-budget-refund.mjs +375 -0
- package/hooks/pre-auq-clarity.mjs +70 -18
- package/hooks/pre-bash-issue-budget.mjs +170 -26
- package/hooks/subagent-telemetry.mjs +106 -20
- package/package.json +5 -4
- package/pi/prompts/ux-grill.md +12 -0
- package/scripts/baseline-archetypes.mjs +28 -0
- package/scripts/ci/assert-vitest-green.mjs +4 -2
- package/scripts/dialectic-deriver.mjs +32 -8
- package/scripts/emit-session.mjs +72 -1
- package/scripts/lib/agent-status.mjs +441 -9
- package/scripts/lib/auq/schema.mjs +10 -3
- 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/ci-status-banner.mjs +29 -6
- package/scripts/lib/claude-md-budget-lint.mjs +52 -2
- 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/config.mjs +12 -1
- package/scripts/lib/eval/engine.mjs +7 -1
- package/scripts/lib/file-lock.mjs +151 -8
- package/scripts/lib/git-porcelain.mjs +113 -0
- package/scripts/lib/instruction-budget-guard.mjs +415 -47
- package/scripts/lib/io.mjs +29 -4
- package/scripts/lib/issue-budget-reconcile.mjs +392 -0
- package/scripts/lib/issue-budget.mjs +412 -9
- package/scripts/lib/learnings/evolve-telemetry.mjs +1 -2
- package/scripts/lib/learnings/sizing-subject.mjs +44 -0
- package/scripts/lib/locks/staging-fence-lock.mjs +19 -38
- package/scripts/lib/locks/state-md-lock.mjs +19 -41
- package/scripts/lib/maintenance-due-banner.mjs +450 -0
- package/scripts/lib/owner-config.example.yaml +29 -46
- package/scripts/lib/owner-yaml.mjs +14 -13
- package/scripts/lib/peer-cards/merger.mjs +143 -0
- package/scripts/lib/pre-dispatch-check.mjs +20 -14
- package/scripts/lib/project-hygiene.mjs +81 -30
- package/scripts/lib/quality-gate.mjs +27 -71
- package/scripts/lib/reconcile/engine.mjs +19 -1
- package/scripts/lib/reconcile/writer.mjs +278 -11
- package/scripts/lib/resource-probe/evaluate.mjs +19 -21
- package/scripts/lib/rules-sync.mjs +34 -4
- package/scripts/lib/scope-echo.mjs +346 -0
- 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-lock.mjs +62 -2
- package/scripts/lib/session-record-repair.mjs +91 -0
- package/scripts/lib/session-schema/constants.mjs +6 -0
- package/scripts/lib/session-schema/filters.mjs +26 -1
- package/scripts/lib/session-schema/validator.mjs +20 -0
- package/scripts/lib/session-shape.mjs +558 -0
- package/scripts/lib/session-start-probes.mjs +429 -56
- 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/test-runner/artifact-paths.mjs +30 -5
- package/scripts/lib/test-runner/issue-reconcile.mjs +45 -8
- package/scripts/lib/tmux-layout/layouts.mjs +62 -4
- package/scripts/lib/ux-grill/collect.mjs +1163 -0
- package/scripts/lib/ux-grill/compare.mjs +285 -0
- package/scripts/lib/ux-grill/manifest.mjs +618 -0
- package/scripts/lib/ux-grill/measures.mjs +431 -0
- package/scripts/lib/ux-grill/paths.mjs +224 -0
- package/scripts/lib/ux-grill/pencil-coverage.mjs +284 -0
- package/scripts/lib/ux-grill/reconcile.mjs +344 -0
- package/scripts/lib/ux-grill/run-record.mjs +316 -0
- package/scripts/lib/ux-grill/schema.mjs +321 -0
- package/scripts/lib/validate/check-skill-script-paths.mjs +33 -10
- package/scripts/lib/validate/check-untracked-test-deps.mjs +33 -19
- package/scripts/lib/validate/check-unwired-features.mjs +56 -27
- package/scripts/lib/vault-mirror/process.mjs +2 -1
- package/scripts/lib/vault-status/board-lock.mjs +18 -0
- package/scripts/lib/vault-status/board-writer.mjs +8 -0
- 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/mcp-server.sh +16 -1
- package/scripts/print-applicable-rules.mjs +7 -6
- package/scripts/print-learnings-index.mjs +3 -2
- package/scripts/release.mjs +7 -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 +60 -209
- 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/references/bootstrap-ecosystem-health-flow.md +48 -0
- package/skills/bootstrap/references/bootstrap-refresh-lock-flow.md +37 -0
- package/skills/bootstrap/references/bootstrap-retroactive-flow.md +108 -0
- package/skills/bootstrap/references/bootstrap-rules-fetch-bridge.md +64 -0
- package/skills/bootstrap/standard-template.md +39 -24
- package/skills/claude-md-drift-check/SKILL.md +9 -2
- package/skills/claude-md-drift-check/checker.mjs +213 -21
- package/skills/discovery/SKILL.md +6 -173
- package/skills/discovery/probes/vault-staleness.mjs +35 -5
- package/skills/discovery/probes-docs.md +8 -4
- package/skills/discovery/probes-supply-chain.md +4 -2
- package/skills/discovery/probes-ui.md +8 -4
- package/skills/discovery/probes-vault.md +12 -4
- package/skills/discovery/references/discovery-interactive-triage.md +139 -0
- package/skills/discovery/references/discovery-triage-state.md +54 -0
- package/skills/docs-orchestrator/audience-mapping.md +1 -1
- package/skills/eval/rubric-v1.md +13 -0
- package/skills/evolve/SKILL.md +2 -458
- package/skills/evolve/references/evolve-analyze-mode.md +360 -0
- package/skills/evolve/references/evolve-dialectic-mode.md +139 -0
- 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/plan/mode-retro.md +4 -3
- package/skills/reconcile/SKILL.md +11 -1
- package/skills/session-end/SKILL.md +3 -2
- package/skills/session-end/drift-operations.md +20 -5
- package/skills/session-end/metrics-collection.md +1 -0
- package/skills/session-end/phase-3-2-docs-verification.md +1 -1
- package/skills/session-end/phase-3-6-tail.md +27 -67
- package/skills/session-end/phase-3-7a-recommendations.md +2 -2
- package/skills/session-end/references/phase-2-quality-gate.md +3 -3
- package/skills/session-end/references/phase-3-documentation-updates.md +8 -6
- package/skills/session-end/references/phase-5-issue-cleanup.md +32 -1
- package/skills/session-end/session-metrics-write.md +33 -12
- package/skills/session-plan/SKILL.md +46 -180
- package/skills/session-plan/references/session-plan-task-classification.md +152 -0
- package/skills/session-plan/wave-template.md +8 -15
- package/skills/session-start/SKILL.md +41 -7
- 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/operations-contract.md +114 -0
- package/skills/session-start/references/phase-1-5-session-continuity.md +2 -0
- package/skills/session-start/references/phase-4-ssot-environment-check.md +42 -24
- package/skills/session-start/references/phase-6-7-memory-banner-telemetry-consent.md +3 -1
- package/skills/session-start/soul.md +2 -2
- package/skills/test-runner/SKILL.md +1 -1
- package/skills/test-runner/rubric-v1.md +2 -2
- package/skills/tmux-layout/SKILL.md +3 -1
- package/skills/ux-grill/SKILL.md +211 -0
- package/skills/ux-grill/rubric-v2.md +201 -0
- package/skills/ux-grill/soul.md +76 -0
- package/skills/wave-executor/SKILL.md +32 -127
- package/skills/wave-executor/circuit-breaker.md +3 -1
- package/skills/wave-executor/references/wave-executor-quality-gate.md +61 -0
- package/skills/wave-executor/references/wave-executor-state-init.md +86 -0
- package/skills/wave-executor/references/wave-loop-dispatch.md +12 -2
- package/skills/wave-executor/references/wave-loop-review.md +19 -6
- package/skills/wave-executor/references/wave-loop-scope-manifest.md +6 -2
- package/templates/_shared/ux-manifest.template.md +149 -0
- 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
- package/templates/_shared/journey-manifest.md +0 -114
|
@@ -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`:
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Bootstrap — Ecosystem-Health Flow (`--ecosystem-health`)
|
|
2
|
+
|
|
3
|
+
> Reference of the `bootstrap` skill, split out of `SKILL.md` (#1246). Body moved **byte-identical**; only this header is new.
|
|
4
|
+
> **Sibling-file paths inside this body are relative to the parent directory, not to `references/`**: `SKILL.md` → `../SKILL.md`. They were deliberately NOT rewritten, so the moved bytes stay verifiable against the pre-split file.
|
|
5
|
+
|
|
6
|
+
## Ecosystem-Health Flow (`--ecosystem-health`)
|
|
7
|
+
|
|
8
|
+
Entered when `$ARGUMENTS` contains `--ecosystem-health`. This is a **standalone flow** — it does not scaffold repo structure and does not write `bootstrap.lock`. Dispatch immediately; do not proceed to Phase 1.
|
|
9
|
+
|
|
10
|
+
**Purpose:** Populate the `health-endpoints`, `pipelines`, and `criticalIssueLabels` configuration consumed by `skills/ecosystem-health/SKILL.md`. Runs the interactive wizard in `scripts/lib/ecosystem-wizard.mjs`, which detects CI provider + package manager automatically and prompts the user for the remaining values.
|
|
11
|
+
|
|
12
|
+
**Steps:**
|
|
13
|
+
|
|
14
|
+
1. **Run the wizard.**
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
node "$PLUGIN_ROOT/scripts/lib/ecosystem-wizard.mjs" --repo-root "$(pwd)"
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The wizard will:
|
|
21
|
+
- Detect CI provider (`.gitlab-ci.yml` → `gitlab`; `.github/workflows/` → `github`; else `none`)
|
|
22
|
+
- Detect package manager from lockfile
|
|
23
|
+
- Prompt for health endpoints (format: `Name|URL`, comma-separated)
|
|
24
|
+
- Prompt for CI pipeline identifiers (format: `id` or `id:label`, comma-separated)
|
|
25
|
+
- Prompt for critical issue labels (comma-separated strings)
|
|
26
|
+
|
|
27
|
+
2. **Wizard writes two files** (or skips each if already present):
|
|
28
|
+
- `CLAUDE.md` (or `AGENTS.md`) — appends `ecosystem-health:` block inside `## Session Config`
|
|
29
|
+
- `.orchestrator/policy/ecosystem.json` — full policy file (schema: `.orchestrator/policy/ecosystem.schema.json`)
|
|
30
|
+
|
|
31
|
+
3. **No auto-commit.** The wizard prints what it wrote. The user reviews with `git status && git diff` and commits manually.
|
|
32
|
+
|
|
33
|
+
**Report:** The wizard prints a one-line summary per file:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
Ecosystem-Health Wizard complete.
|
|
37
|
+
Written: .orchestrator/policy/ecosystem.json, CLAUDE.md
|
|
38
|
+
Skipped (already present): (none)
|
|
39
|
+
|
|
40
|
+
Review changes with: git status && git diff
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Idempotency:** Safe to re-run. If both output files are already present with matching content, the wizard exits 0 with "Nothing to do." To update, remove the existing `ecosystem-health:` key from Session Config and delete `.orchestrator/policy/ecosystem.json`, then re-run.
|
|
44
|
+
|
|
45
|
+
See `skills/ecosystem-health/wizard.md` for the full prompt spec and schema details.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Bootstrap — Refresh-Lock Flow (`--refresh-lock`)
|
|
2
|
+
|
|
3
|
+
> Reference of the `bootstrap` skill, split out of `SKILL.md` (#1246). Body moved **byte-identical**; only this header is new.
|
|
4
|
+
> **Sibling-file paths inside this body are relative to the parent directory, not to `references/`**: `SKILL.md` → `../SKILL.md`. They were deliberately NOT rewritten, so the moved bytes stay verifiable against the pre-split file.
|
|
5
|
+
|
|
6
|
+
## Refresh-Lock Flow (`--refresh-lock`)
|
|
7
|
+
|
|
8
|
+
Entered when `$ARGUMENTS` contains `--refresh-lock`. No scaffolding questions are asked, and — unlike the Retroactive Flow above — this is NOT a no-op once the lock already has valid `version`/`tier` fields: refreshing is the load-bearing action.
|
|
9
|
+
|
|
10
|
+
**Purpose (#57):** Acknowledge the current plugin version and reset the freshness clock on an existing, already-valid `bootstrap.lock` without disturbing its original bootstrap provenance. This closes the gap left by the Retroactive Flow: once a lock already has `version` + `tier`, re-running `/bootstrap --retroactive` reports "bootstrap.lock already present ... Nothing to do." and changes nothing — exactly the no-op the bootstrap-lock-freshness probe (#186/#290) was recommending as its remediation. `--refresh-lock` is the actual remediation for a present-but-stale or version-drifted lock.
|
|
11
|
+
|
|
12
|
+
**Steps:**
|
|
13
|
+
|
|
14
|
+
1. **Precondition check.** Read `.orchestrator/bootstrap.lock`. If missing, or present but missing a non-empty `version` or `tier` field, abort with: `Error: No valid bootstrap.lock found. Run /bootstrap or /bootstrap --retroactive first.` Do not fabricate a lock — this flow only refreshes an existing one.
|
|
15
|
+
|
|
16
|
+
2. **Resolve the current plugin version.** Read `plugin-version` from `$PLUGIN_ROOT/package.json` (same source Phase 4 uses).
|
|
17
|
+
|
|
18
|
+
3. **Call the refresh writer.**
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
import { refreshBootstrapLock } from '$PLUGIN_ROOT/scripts/lib/bootstrap-lock-refresh.mjs';
|
|
22
|
+
const result = refreshBootstrapLock({
|
|
23
|
+
repoRoot: REPO_ROOT,
|
|
24
|
+
currentPluginVersion: PLUGIN_VERSION,
|
|
25
|
+
});
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`refreshBootstrapLock` writes (or replaces, if already present) exactly two lines — `refreshed-at: <ISO 8601 UTC>` and `refreshed-plugin-version: <current plugin version>` — via the same atomic tmp-file + rename pattern used by the Retroactive Flow's lock write: write to a sibling tmp file, then rename over the target so the lock is never observed half-written. **Every other line of the lock — `bootstrapped-at`, `timestamp`, `plugin-version`, `tier`, `archetype`, `source`, … — is left byte-identical.** This is the provenance-honesty guarantee: a refresh is an acknowledgement, not a re-bootstrap. On failure (`result.ok === false`), surface `result.message` and stop — do not retry with a fabricated lock.
|
|
29
|
+
|
|
30
|
+
4. **No auto-commit.** Unlike the Retroactive Flow, `--refresh-lock` does not stage or commit. The refreshed lock is a small, reviewable diff (two changed/added lines); the user commits it alongside their own work at their own cadence.
|
|
31
|
+
|
|
32
|
+
5. **Report.** Print: `Lock refreshed (refreshed-at: <now>, plugin-version: <current>). Original bootstrap provenance unchanged.`
|
|
33
|
+
|
|
34
|
+
**Idempotency.** Running `/bootstrap --refresh-lock` twice in a row replaces the same two lines in place — it never duplicates them.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Bootstrap — Retroactive Flow (`--retroactive`)
|
|
2
|
+
|
|
3
|
+
> Reference of the `bootstrap` skill, split out of `SKILL.md` (#1246). Body moved **byte-identical**; only this header is new.
|
|
4
|
+
> **Sibling-file paths inside this body are relative to the parent directory, not to `references/`**: `SKILL.md` → `../SKILL.md`. They were deliberately NOT rewritten, so the moved bytes stay verifiable against the pre-split file.
|
|
5
|
+
|
|
6
|
+
## Retroactive Flow (`--retroactive`)
|
|
7
|
+
|
|
8
|
+
Entered when `$ARGUMENTS` contains `--retroactive`. Writes the lock file and, per #182, optionally patches missing mandatory Session Config fields with defaults.
|
|
9
|
+
|
|
10
|
+
**Purpose:** Adopt an existing repo that already has `CLAUDE.md` + `## Session Config` but was bootstrapped manually (no `bootstrap.lock`). Writes the lock so the gate passes on all future invocations, and ensures the Session Config block satisfies the validated schema defined in `scripts/lib/config-schema.mjs`.
|
|
11
|
+
|
|
12
|
+
**Steps:**
|
|
13
|
+
|
|
14
|
+
1. **Verify preconditions.** Confirm `CLAUDE.md` (or `AGENTS.md`) exists and contains `## Session Config`. If not, abort: `Error: CLAUDE.md with Session Config required for retroactive bootstrap.`
|
|
15
|
+
|
|
16
|
+
2. **Check lock not already present.** If `.orchestrator/bootstrap.lock` already exists and has valid `version` + `tier` fields, report: `bootstrap.lock already present (tier: <tier>). Nothing to do.` and exit 0 (idempotent).
|
|
17
|
+
|
|
18
|
+
3. **Infer tier from file inventory.** Examine the repo root:
|
|
19
|
+
|
|
20
|
+
| Condition (evaluated in order) | Inferred Tier |
|
|
21
|
+
|---|---|
|
|
22
|
+
| CI file present (`.gitlab-ci.yml` OR `.github/workflows/`) AND `CHANGELOG.md` present | `deep` |
|
|
23
|
+
| Package manifest present (`package.json` OR `pyproject.toml`) | `standard` |
|
|
24
|
+
| Neither of the above | `fast` |
|
|
25
|
+
|
|
26
|
+
Store as `INFERRED_TIER`.
|
|
27
|
+
|
|
28
|
+
4. **Infer archetype.** Run Phase 0.5's read-only source detection. For a private
|
|
29
|
+
contract, use its detected `selected.id`; retain `null` with an explicit
|
|
30
|
+
`insufficient-evidence` report if no markers match. An invalid configured
|
|
31
|
+
contract aborts. Do not scaffold or apply rules in this retroactive flow.
|
|
32
|
+
For the public path, use best-effort detection from existing files:
|
|
33
|
+
- `pyproject.toml` present → `python-uv`
|
|
34
|
+
- `package.json` with `next` in dependencies → `nextjs-minimal`
|
|
35
|
+
- `package.json` without `next` → `node-minimal`
|
|
36
|
+
- No manifest → `null`
|
|
37
|
+
|
|
38
|
+
Store as `INFERRED_ARCHETYPE`.
|
|
39
|
+
|
|
40
|
+
5. **Write bootstrap.lock.** Create `.orchestrator/` if needed, then write:
|
|
41
|
+
```yaml
|
|
42
|
+
# .orchestrator/bootstrap.lock
|
|
43
|
+
version: 1
|
|
44
|
+
tier: <INFERRED_TIER>
|
|
45
|
+
archetype: <INFERRED_ARCHETYPE or null>
|
|
46
|
+
timestamp: <current ISO 8601 UTC>
|
|
47
|
+
source: retroactive
|
|
48
|
+
plugin-version: <current plugin version from $PLUGIN_ROOT/package.json>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
6. **Patch Session Config (#182).** Run the validator against the current `## Session Config` block; append any missing mandatory fields with defaults. The 7 mandatory fields (per `scripts/lib/config-schema.mjs`) are: `test-command`, `typecheck-command`, `lint-command`, `agents-per-wave`, `waves`, `persistence`, `enforcement`.
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
CONFIG_OUT="$(node "$PLUGIN_ROOT/scripts/parse-config.mjs" 2>&1 >/dev/null)"
|
|
55
|
+
# parse-config.mjs emits validation warnings to stderr when enforcement=warn.
|
|
56
|
+
# Grep for 'must be' lines (issued by validate-config.mjs) to detect missing fields.
|
|
57
|
+
MISSING_FIELDS="$(echo "$CONFIG_OUT" | grep -oE '(test-command|typecheck-command|lint-command|agents-per-wave|waves|persistence|enforcement)' | sort -u || true)"
|
|
58
|
+
if [[ -n "$MISSING_FIELDS" ]]; then
|
|
59
|
+
# Detect package manager to pick sensible defaults for commands.
|
|
60
|
+
PM_DEFAULTS="$(node --input-type=module -e "
|
|
61
|
+
import {detectPackageManager, defaultQualityGateCommands} from '$PLUGIN_ROOT/scripts/lib/package-manager.mjs';
|
|
62
|
+
const pm = detectPackageManager(process.cwd());
|
|
63
|
+
const cmds = defaultQualityGateCommands(pm);
|
|
64
|
+
console.log('test-command: ' + cmds.test.command);
|
|
65
|
+
console.log('typecheck-command: ' + cmds.typecheck.command);
|
|
66
|
+
console.log('lint-command: ' + cmds.lint.command);
|
|
67
|
+
" 2>/dev/null)"
|
|
68
|
+
|
|
69
|
+
CONFIG_FILE="CLAUDE.md"
|
|
70
|
+
[[ -f "AGENTS.md" ]] && CONFIG_FILE="AGENTS.md"
|
|
71
|
+
|
|
72
|
+
# Append each missing field under the ## Session Config block.
|
|
73
|
+
for field in $MISSING_FIELDS; do
|
|
74
|
+
case "$field" in
|
|
75
|
+
test-command|typecheck-command|lint-command)
|
|
76
|
+
default_line="$(echo "$PM_DEFAULTS" | grep "^$field:")" ;;
|
|
77
|
+
agents-per-wave) default_line="agents-per-wave: 6" ;;
|
|
78
|
+
waves) default_line="waves: 5" ;;
|
|
79
|
+
persistence) default_line="persistence: true" ;;
|
|
80
|
+
enforcement) default_line="enforcement: warn" ;;
|
|
81
|
+
esac
|
|
82
|
+
# Insert after `## Session Config` line if not already present.
|
|
83
|
+
grep -q "^$field:" "$CONFIG_FILE" \
|
|
84
|
+
|| awk -v insert="$default_line" '/^## Session Config/ && !done { print; print ""; print insert; done=1; next } { print }' "$CONFIG_FILE" > "$CONFIG_FILE.tmp" \
|
|
85
|
+
&& mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
|
|
86
|
+
done
|
|
87
|
+
echo "Patched $CONFIG_FILE with defaults for: $MISSING_FIELDS"
|
|
88
|
+
fi
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
This patch is best-effort: existing fields are never overwritten. If no fields are missing, this step is a no-op.
|
|
92
|
+
|
|
93
|
+
7. **Commit.** Stage the lock file (and the patched config file, if it changed) and commit:
|
|
94
|
+
```bash
|
|
95
|
+
mkdir -p .orchestrator
|
|
96
|
+
git add .orchestrator/bootstrap.lock
|
|
97
|
+
# Also stage CLAUDE.md/AGENTS.md if step 6 patched it.
|
|
98
|
+
git diff --name-only --cached CLAUDE.md AGENTS.md 2>/dev/null | head -1 >/dev/null || {
|
|
99
|
+
[[ -f CLAUDE.md ]] && git diff --quiet CLAUDE.md || git add CLAUDE.md
|
|
100
|
+
[[ -f AGENTS.md ]] && git diff --quiet AGENTS.md || git add AGENTS.md
|
|
101
|
+
}
|
|
102
|
+
git commit -m "chore: bootstrap lock (retroactive)"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
8. **Report.** Print: `Retroactive bootstrap complete. Lock written (tier: <INFERRED_TIER>, source: retroactive).` Include a second line `Patched Session Config: <fields>` when step 6 applied any patches, otherwise `No config changes.`.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Bootstrap — Phase 3.6: (Optional) Rules-Fetch Bridge
|
|
2
|
+
|
|
3
|
+
> Reference of the `bootstrap` skill, split out of `SKILL.md` (#1246). Body moved **byte-identical**; only this header is new.
|
|
4
|
+
> **Sibling-file paths inside this body are relative to the parent directory, not to `references/`**: `SKILL.md` → `../SKILL.md`, `private-contract.md` → `../private-contract.md`, `standard-template.md` → `../standard-template.md`, `deep-template.md` → `../deep-template.md`. They were deliberately NOT rewritten, so the moved bytes stay verifiable against the pre-split file.
|
|
5
|
+
|
|
6
|
+
## Phase 3.6: (Optional) Rules-Fetch Bridge
|
|
7
|
+
|
|
8
|
+
> Closes session-orchestrator issue #110.
|
|
9
|
+
|
|
10
|
+
After scaffolding, the Standard and Deep templates execute S99. On the private
|
|
11
|
+
path, it applies the selected contract's local rule union, rechecks conditional
|
|
12
|
+
dependencies and preserves existing files. It excludes every plugin-owned
|
|
13
|
+
basename and aborts on an invalid configured contract; see `private-contract.md`.
|
|
14
|
+
|
|
15
|
+
On the public path, S99 retains the optional remote rules-fetch step. It pulls
|
|
16
|
+
canonical `.claude/rules/*.md` directly from the configured baseline GitLab
|
|
17
|
+
project, excluding all plugin-owned basenames. The remote step only fires when:
|
|
18
|
+
|
|
19
|
+
- `baseline-ref` is present in Session Config
|
|
20
|
+
- `GITLAB_TOKEN` env var is set
|
|
21
|
+
- `scripts/lib/fetch-baseline.mjs` is present in the plugin
|
|
22
|
+
- A GitLab host is resolvable from the `gitlab-host` Session Config key (or the `GITLAB_HOST` env var) — never a hardcoded default
|
|
23
|
+
|
|
24
|
+
When triggered, the step:
|
|
25
|
+
|
|
26
|
+
1. Loops over a default rule manifest, invoking `node scripts/lib/fetch-baseline.mjs <project_id> <file_path> <baseline-ref>` once per rule. The CLI prints one file body to stdout (exit 0 success; 1 auth, 2 not-found, 3 network) — bootstrap redirects stdout to the target path and skips failures so a single 404 cannot abort the batch.
|
|
27
|
+
2. Fetches each rule listed in the default manifest from the configured `baseline-project-id` (default `52`) at the configured `baseline-ref`
|
|
28
|
+
3. Writes `.claude/.baseline-fetch.lock` (via an inline `node --input-type=module -e`) recording what was fetched
|
|
29
|
+
4. Populates `.claude/.baseline-cache/` for offline fallback on subsequent invocations
|
|
30
|
+
|
|
31
|
+
When the fetch fails (network error, auth, missing file), bootstrap **does not abort**. Rules will arrive in the repo via Clank's weekly baseline sync MRs (the legacy path). A warning is printed.
|
|
32
|
+
|
|
33
|
+
**Why opt-in:** Repos without `baseline-ref` continue to receive rules via the existing Clank sync flow. The fetch bridge is a faster on-demand alternative for newly-bootstrapped repos that want current rules immediately.
|
|
34
|
+
|
|
35
|
+
**Local edits:** Re-running bootstrap with `baseline-ref` set will overwrite `.claude/rules/*.md` (rules are canonical). Repo-specific extensions belong in `.claude/rules/local/*.md` (not fetched, not overwritten).
|
|
36
|
+
|
|
37
|
+
See `standard-template.md` (Step S99) and `deep-template.md` (Step D99) for the implementation, and `docs/session-config-reference.md` for the `baseline-ref` and `baseline-project-id` field definitions.
|
|
38
|
+
|
|
39
|
+
### `.claude/.baseline-fetch.lock` Schema
|
|
40
|
+
|
|
41
|
+
The lock file is committed to git and records what was fetched.
|
|
42
|
+
|
|
43
|
+
```yaml
|
|
44
|
+
# .claude/.baseline-fetch.lock
|
|
45
|
+
version: 1
|
|
46
|
+
project_id: 52
|
|
47
|
+
baseline_ref: main
|
|
48
|
+
fetched_at: 2026-04-17T13:42:00Z # ISO 8601 UTC
|
|
49
|
+
files:
|
|
50
|
+
- .claude/rules/development.md
|
|
51
|
+
- .claude/rules/security.md
|
|
52
|
+
- .claude/rules/...
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
| Field | Description |
|
|
56
|
+
|---|---|
|
|
57
|
+
| `version` | Lock file schema version. Currently `1`. |
|
|
58
|
+
| `project_id` | GitLab project ID the files were fetched from. |
|
|
59
|
+
| `baseline_ref` | The git ref (branch/tag/SHA) at fetch time. |
|
|
60
|
+
| `fetched_at` | ISO 8601 UTC timestamp. |
|
|
61
|
+
| `files` | List of fetched file paths (relative to repo root). |
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
@@ -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
|
```
|
|
@@ -41,7 +41,7 @@ PHASE 1 IMPLEMENTED (2026-04-19). Session-end opt-in quality gate. Upstream of `
|
|
|
41
41
|
| 6 | `session-config-parity` | Top-level keys under `## Session Config` in `CLAUDE.md` / `AGENTS.md` | diff against `docs/session-config-template.md`; a missing MANDATORY (minimal-baseline) key is an error, a missing OPT-IN-baseline-only key is a warning |
|
|
42
42
|
| 7 | `vault-dir-parity` | `vault-integration.vault-dir` in BOTH `CLAUDE.md` AND `AGENTS.md` | reuse `_parseVaultIntegration`; flag when the two files disagree. Short-circuits to PASS when the two are the SAME file by construction (symlink / same inode / byte-identical generated copy) |
|
|
43
43
|
| 8 | `generated-rule-staleness` *(WARN only)* | `.claude/rules/*.md` with `auto-generated: true` frontmatter | extract `learning-key`; WARN when the key is absent from `.orchestrator/metrics/learnings.jsonl` or its learning's `expires_at` is in the past; skipped silently when no auto-generated rules exist |
|
|
44
|
-
| 9 | `rule-scoping` | `.claude/rules/*.md` frontmatter + `## See Also` footers + `.claude/rules/<name>.md` citations in `CLAUDE.md`/`AGENTS.md` |
|
|
44
|
+
| 9 | `rule-scoping` | `.claude/rules/*.md` frontmatter + `## See Also` footers + `.claude/rules/<name>.md` citations in `CLAUDE.md`/`AGENTS.md` | six probes: `paths:` frontmatter (error), cited-but-missing rule citations (error), zero-match `globs:` patterns (warn), foreign PascalCase glob tokens (warn), unreadable rule files (warn — surfaced instead of silently skipped), declared fleet-intent globs (**note**, never warn); skipped silently when `.claude/rules/` is absent |
|
|
45
45
|
| 10 | `docs-parity` | `docs/components.md` count-claims, Session Config key parity (`docs/session-config-template.md` vs `docs/session-config-reference.md`), `.claude/metrics/` stale-path references in `docs/*.md` / `docs/examples/*.md` | three sub-checks (a/b/c) — see below; skipped silently when `docs/components.md` is absent |
|
|
46
46
|
|
|
47
47
|
Check 3 deliberately scopes to forward-looking sections. Mentions inside "Recently Closed", "Decisions", "Archive", etc. describe history and must not be flagged.
|
|
@@ -65,7 +65,9 @@ Check 7 (issue #600) is the **only** check that intentionally reads BOTH instruc
|
|
|
65
65
|
|
|
66
66
|
The same predicate guards Check 9's probe 2a, which iterates `['CLAUDE.md', 'AGENTS.md']`: with an aliased `AGENTS.md` it scans `CLAUDE.md` only, because otherwise every dangling `.claude/rules/*.md` citation would be reported TWICE — one defect, two errors, and in `--mode strict` a doubled blocking surface against a file the operator is not allowed to edit.
|
|
67
67
|
|
|
68
|
-
Check 9 (`rule-scoping`) validates `.claude/rules/*.md` frontmatter against the `scripts/lib/rule-loader.mjs` contract, catching the class of defect where a rule silently drifts out of the activation pipeline the loader actually implements.
|
|
68
|
+
Check 9 (`rule-scoping`) validates `.claude/rules/*.md` frontmatter against the `scripts/lib/rule-loader.mjs` contract, catching the class of defect where a rule silently drifts out of the activation pipeline the loader actually implements. Six probes: **(1) paths-presence** — a top-level `paths:` frontmatter key is not a key `rule-loader.mjs` recognises (it only reads `globs:`), so a rule with `paths:` silently loads ALWAYS-ON regardless of intended file scope; flagged as an error. **(2) cited-but-missing** — `(a)` `.claude/rules/<name>.md` citations inside `CLAUDE.md`/`AGENTS.md` that don't resolve to a file on disk, and `(b)` bare `<name>.md` tokens in a rule's own `## See Also` footer that don't exist as sibling rule files (tokens carrying a path separator, e.g. `../../skills/_shared/state-ownership.md`, are cross-directory references and explicitly out of scope); both flagged as errors. **(3) zero-match-globs** — a `globs:` pattern matching zero files in `git ls-files` (falls back to a manual directory walk when git is unavailable); flagged as a WARNING, not an error, because library/exemplar repos legitimately carry dead stack rules. **(4) foreign-glob** — a glob pattern containing a PascalCase product-like token (regex `[A-Z][a-z]+[A-Z]`, e.g. `WalkAITalkieTests`) — a likely copy-paste leftover from another project's rule scope; flagged as a WARNING. **(5) unreadable-file** — a rule file that could not be read (permissions, a race with a concurrent delete); flagged as a WARNING rather than silently skipped, so a completeness audit does not drop files, and so an unreadable file cannot brick the gate under `mode: hard`. **(6) fleet-intent-glob** — a `globs:` pattern DECLARED as fleet intent goes to `notes[]` (see below), never to `warnings[]`, and the declaration also settles probe 4 for that same pattern: a pattern the rule author declared is by construction not a copy-paste leftover. Glob matching reuses the same picomatch-with-inline-fallback resolution `scripts/lib/rule-loader.mjs` uses (`parseGlobsFrontmatter` is imported directly; the picomatch resolution itself is duplicated locally since `rule-loader.mjs` does not export a public matcher function). The check is skipped silently (no `checks_run` entry, no `checks_skipped` entry) when `.claude/rules/` is absent, or explicitly via `--skip-rule-scoping`.
|
|
69
|
+
|
|
70
|
+
**Fleet-intent declaration (Check 9, probe 6).** A rule may declare that a `globs:` pattern is aimed at CONSUMER repos rather than this one, via its own frontmatter key `fleet-intent-globs:`. Accepted forms are block style (`fleet-intent-globs:` plus indented ` - "<pattern>"` lines), flow style (`fleet-intent-globs: ["a", "b"]`) and a single inline value; surrounding quotes are stripped, blank and `#` comment lines are ignored. The key is inert for rule loading — `rule-loader.mjs`'s `parseGlobsFrontmatter` skips unknown top-level keys and their continuation lines. A declared pattern is reported in `notes[]` with its file, the pattern, whether it matches `≥1` or `0` tracked files here, and the declaration `source` (`frontmatter`). The grain is per pattern AND per rule file: declaring one glob amnesties neither a sibling glob in the same rule nor the same pattern in another rule. There is deliberately NO checker-side exemption list: a rule that does not declare the pattern itself is not exempt, so the declaration always sits with the rule it describes.
|
|
69
71
|
|
|
70
72
|
Check 10 (`docs-parity`, issue #780) validates the public docs surface against live repository state via three sub-checks, all reported under the single `docs-parity` check id: **(a) count-claims** — `docs/components.md`'s own heading counts ("## Skills (N user-facing)", "## Commands (N)", "## Agents (N typed sub-agents)", "## Hook event types (N)") are compared against the SAME actual on-disk derivation the surface-count family (Check 5) uses (`countSkills`/the commands-dir listing/`countAgents`/`readHookCounts`) — NOT Check 5's `claimRe` regexes, which are tuned for CLAUDE.md/README prose phrasing and verifiably do not match `components.md`'s own heading convention; a dedicated set of regexes tailored to the doc's actual authored structure is used instead. **(b) config-block-parity** — top-level Session Config keys documented in `docs/session-config-template.md` (opt-in baseline, via the Check 6 'last'-occurrence extractor) are compared against `docs/session-config-reference.md`; a key is considered documented in the reference when it appears in a `yaml` fence (any indent), a `##`/`###`/`####` heading, or the first cell of a markdown table row (`` | `key-name` | ... ``) — the reference's dominant documentation shape is one table row per field, so a naive fence-only extraction under-counts what it actually documents. Missing keys surface as `docs-parity` errors attributed to `docs/session-config-reference.md`. **(c) metrics-path-liveness** — any `.claude/metrics/` path reference (stale; canonical is `.orchestrator/metrics/`) found in root `docs/*.md` or `docs/examples/*.md` surfaces as an error at its exact file/line. The whole check is skipped silently (no `checks_run` entry, no `checks_skipped` entry) when `docs/components.md` is absent, or explicitly via `--skip-docs-parity`.
|
|
71
73
|
|
|
@@ -124,10 +126,15 @@ Environment:
|
|
|
124
126
|
"warnings": [
|
|
125
127
|
{ "check": "<name>", "file": "<relative path>", "line": N, "message": "<human>", "extracted": "<raw text>" }
|
|
126
128
|
],
|
|
129
|
+
"notes": [
|
|
130
|
+
{ "check": "rule-scoping", "probe": "fleet-intent-glob", "file": "<relative path>", "line": N, "message": "<human>", "extracted": "<pattern>", "source": "frontmatter" }
|
|
131
|
+
],
|
|
127
132
|
"command_count": { "actual": N }
|
|
128
133
|
}
|
|
129
134
|
```
|
|
130
135
|
|
|
136
|
+
`notes[]` is the THIRD output category, alongside `errors[]` and `warnings[]`: a finding that is reported but asks for no action. It never affects `status` or the exit code, and it is always present (empty array when nothing was noted, including on the short-circuit "no scope files matched" path). Its only producer today is Check 9's fleet-intent-glob probe.
|
|
137
|
+
|
|
131
138
|
The `resolved_path` / `resolved_kind` pair surfaces the alias resolution outcome (issue #33 AC2) so users on either platform can audit which instruction file the checker scanned. `kind: 'claude'` for `CLAUDE.md`, `kind: 'agents'` for `AGENTS.md`, `null` when neither was found.
|
|
132
139
|
|
|
133
140
|
When `command-count` fires a drift error, the error object also carries `"command_count": { "actual": N, "claimed": M }` for easy programmatic diffing.
|