# Bootstrap Deep Template

> Scaffold instructions for the Deep tier.
> Called from `skills/bootstrap/SKILL.md` Phase 3 when `CONFIRMED_TIER = deep`.

Deep tier is a strict superset of Standard tier. Execute all Standard-tier steps first, then the Deep-specific steps below.

## Step 1–8: Execute Standard Tier

Read and execute `skills/bootstrap/standard-template.md` Steps 1–8 in full. Do not skip any step.

**Exception to standard-template Step 6 (bootstrap.lock):** Do not write `.orchestrator/bootstrap.lock` yet. The lock is written with `tier: deep` at Deep Step 6.

**Exception to standard-template Step 7 (git commit):** Do not run the git commit in standard-template Step 7. All files (Fast + Standard + Deep) are committed together at Deep Step 7.

---

## VCS Detection

Before executing the Deep-specific steps, resolve the `VCS` value from Session Config:

```bash
VCS=$(grep -m1 "^vcs:" "$REPO_ROOT/CLAUDE.md" 2>/dev/null | awk '{print $2}')
# Expected values: gitlab | github | none
```

If `VCS` is empty or `none`, skip CI pipeline, issue templates, MR/PR template, and branch protection. Log: "VCS not configured — CI and templates skipped."

---

## Step D1: CI Pipeline

Create the CI pipeline file. Mutually exclusive — create exactly one based on `VCS`.

### If `VCS = gitlab`: `.gitlab-ci.yml`

Write `.gitlab-ci.yml`:

```yaml
# .gitlab-ci.yml — generated by session-orchestrator bootstrap (deep)

stages:
  - test

default:
  image: node:22-alpine  # replace with python:3.12-slim for python-uv archetype

variables:
  FF_USE_FASTZIP: "true"

cache:
  key: "${CI_COMMIT_REF_SLUG}"
  paths:
    - node_modules/   # replace with .venv/ for python-uv

test:
  stage: test
  before_script:
    - corepack enable
    - pnpm install --frozen-lockfile
    # python-uv: replace above two lines with: pip install uv && uv sync
  script:
    - pnpm run build
    - pnpm run lint
    - pnpm run test
    # python-uv: replace above with: uv run ruff check . && uv run pytest
  coverage: '/Lines\s*:\s*(\d+\.?\d*)%/'
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage/cobertura-coverage.xml
    expire_in: 1 week
```

**Archetype adjustment:** If `CONFIRMED_ARCHETYPE = python-uv`, the LLM must substitute the Python variants of the `image`, `cache`, `before_script`, and `script` entries (comments in the template above mark the substitution points). If `CONFIRMED_ARCHETYPE = static-html`, replace `script` with a simple `echo "Static project — no build step."` and remove the `before_script`.

### If `VCS = github`: `.github/workflows/ci.yml`

```bash
mkdir -p "$REPO_ROOT/.github/workflows"
```

Write `.github/workflows/ci.yml`:

```yaml
# .github/workflows/ci.yml — generated by session-orchestrator bootstrap (deep)

name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: pnpm/action-setup@v4
        with:
          version: latest
      # python-uv: replace above two steps with: uses: astral-sh/setup-uv@v5

      - uses: actions/setup-node@v4
        with:
          node-version: "22"
          cache: "pnpm"
      # python-uv: replace above with: uses: actions/setup-python@v5 with python-version: "3.12"

      - name: Install dependencies
        run: pnpm install --frozen-lockfile
        # python-uv: replace with: uv sync

      - name: Build
        run: pnpm run build
        # python-uv: remove this step

      - name: Lint
        run: pnpm run lint
        # python-uv: replace with: uv run ruff check .

      - name: Test
        run: pnpm run test
        # python-uv: replace with: uv run pytest
```

**Archetype adjustment:** Same rules as the GitLab template above. Apply the Python/static-html variants where indicated by comments.

---

## Step D2: CODEOWNERS

Detect the repo owner from git config or Session Config:

```bash
OWNER=$(git config user.email 2>/dev/null || echo "PLACEHOLDER_OWNER")
```

### If `VCS = gitlab`

```bash
mkdir -p "$REPO_ROOT"
```

Write `CODEOWNERS`:

```
# CODEOWNERS — generated by session-orchestrator bootstrap (deep)
# Format: <pattern> <@user-or-group>
# GitLab docs: https://docs.gitlab.com/ee/user/project/codeowners/

* @<OWNER or PLACEHOLDER_OWNER>
```

### If `VCS = github`

Write `.github/CODEOWNERS`:

```bash
mkdir -p "$REPO_ROOT/.github"
```

```
# CODEOWNERS — generated by session-orchestrator bootstrap (deep)
# Format: <pattern> @<github-username>
# GitHub docs: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners

* @<OWNER or PLACEHOLDER_OWNER>
```

Replace `<OWNER or PLACEHOLDER_OWNER>` with the detected `git config user.email` or the literal string `PLACEHOLDER_OWNER` if detection fails. Add an inline comment: `# Replace PLACEHOLDER_OWNER with your GitLab/GitHub username`.

---

## Step D3: CHANGELOG.md

Write `CHANGELOG.md` in the repo root:

```markdown
# Changelog

All notable changes to this project will be documented in this file.

The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [Unreleased]

## [0.1.0] — <YYYY-MM-DD>

### Added

- Initial bootstrap via /plan (deep)
```

Replace `<YYYY-MM-DD>` with today's date in ISO 8601 format (e.g., `2026-04-16`).

---

## Step D4: Issue Templates

### If `VCS = gitlab`

```bash
mkdir -p "$REPO_ROOT/.gitlab/issue_templates"
```

Write `.gitlab/issue_templates/Bug.md`:

```markdown
## Summary

<!-- One-sentence description of the bug -->

## Steps to Reproduce

1.
2.
3.

## Expected Behaviour

<!-- What should happen -->

## Actual Behaviour

<!-- What happens instead -->

## Environment

- Version / branch:
- OS / platform:

## Additional Context

<!-- Screenshots, logs, related issues -->
```

Write `.gitlab/issue_templates/Feature.md`:

```markdown
## Summary

<!-- One-sentence description of the feature request -->

## Motivation

<!-- Why is this feature valuable? Who benefits? -->

## Proposed Solution

<!-- Describe how you envision the implementation -->

## Acceptance Criteria

- [ ]
- [ ]

## Additional Context
```

### If `VCS = github`

```bash
mkdir -p "$REPO_ROOT/.github/ISSUE_TEMPLATE"
```

Write `.github/ISSUE_TEMPLATE/bug_report.md`:

```markdown
---
name: Bug Report
about: Report a bug or unexpected behaviour
labels: bug
---

## Summary

<!-- One-sentence description of the bug -->

## Steps to Reproduce

1.
2.
3.

## Expected Behaviour

## Actual Behaviour

## Environment

- Version / branch:
- OS / platform:

## Additional Context
```

Write `.github/ISSUE_TEMPLATE/feature_request.md`:

```markdown
---
name: Feature Request
about: Propose a new feature or improvement
labels: enhancement
---

## Summary

<!-- One-sentence description of the feature request -->

## Motivation

## Proposed Solution

## Acceptance Criteria

- [ ]
- [ ]

## Additional Context
```

---

## Step D5: MR / PR Template

### If `VCS = gitlab`

```bash
mkdir -p "$REPO_ROOT/.gitlab/merge_request_templates"
```

Write `.gitlab/merge_request_templates/Default.md`:

```markdown
## Summary

<!-- What does this MR do and why? -->

## Changes

- 
- 

## Test Plan

- [ ] Existing tests pass (`pnpm test` / `uv run pytest`)
- [ ] New tests added where appropriate
- [ ] Manually tested

## Related Issues

Closes #

## Checklist

- [ ] Code follows project conventions
- [ ] No secrets or credentials committed
- [ ] CHANGELOG updated if user-facing change
```

### If `VCS = github`

Write `.github/pull_request_template.md`:

```markdown
## Summary

<!-- What does this PR do and why? -->

## Changes

- 
- 

## Test Plan

- [ ] Existing tests pass (`pnpm test` / `uv run pytest`)
- [ ] New tests added where appropriate
- [ ] Manually tested

## Related Issues

Closes #

## Checklist

- [ ] Code follows project conventions
- [ ] No secrets or credentials committed
- [ ] CHANGELOG updated if user-facing change
```

---

## Step D6: Branch Protection

Invoke exactly ONE API call to set branch protection on `main`. Skip this step if `VCS = none`.

### If `VCS = gitlab`

Detect the project path from the git remote:

```bash
REMOTE_URL=$(git remote get-url origin 2>/dev/null)
# Extract namespace/project from URL, e.g. "mygroup/myrepo"
PROJECT_PATH=$(echo "$REMOTE_URL" | sed 's|.*gitlab[^/]*/||; s|\.git$||')
ENCODED_PATH=$(python3 -c "import sys,urllib.parse; print(urllib.parse.quote(sys.argv[1],safe=''))" "$PROJECT_PATH" 2>/dev/null || \
  node -e "process.stdout.write(encodeURIComponent(process.argv[1]))" "$PROJECT_PATH" 2>/dev/null || \
  echo "$PROJECT_PATH" | sed 's|/|%2F|g')
```

```bash
_API_ERR=$(mktemp)
if glab api "projects/$ENCODED_PATH/protected_branches" \
  --method POST \
  -f name="main" \
  -f push_access_level=40 \
  -f merge_access_level=40 \
  -f allow_force_push=false >/dev/null 2>"$_API_ERR"; then
  echo "Branch protection on main: OK"
else
  echo "Branch protection on main: failed (branch may already be protected or insufficient permissions)"
fi
rm -f "$_API_ERR"
```

Access level 40 = Maintainer. If the call fails (e.g., branch already protected, insufficient permissions), log the structured message above and continue — do not abort bootstrap. Raw API response bodies are never echoed to avoid leaking token or header information.

### If `VCS = github`

```bash
REPO_SLUG=$(git remote get-url origin 2>/dev/null | sed 's|.*github\.com[:/]||; s|\.git$||')
```

```bash
_API_ERR=$(mktemp)
if gh api "repos/$REPO_SLUG/branches/main/protection" \
  --method PUT \
  --field required_status_checks=null \
  --field enforce_admins=true \
  --field required_pull_request_reviews='{"required_approving_review_count":1}' \
  --field restrictions=null >/dev/null 2>"$_API_ERR"; then
  echo "Branch protection on main: OK"
else
  echo "Branch protection on main: failed (branch may already be protected or insufficient permissions)"
fi
rm -f "$_API_ERR"
```

If the call fails, log the structured message above and continue. Raw API response bodies are never echoed to avoid leaking token or header information.

---

<!-- @include _shared-template.md#parallel-sessions-rule -->
## Step 3a: Install Parallel-Sessions Rule

Canonical implementation in [`_shared-template.md#parallel-sessions-rule`](_shared-template.md).

Write the vendored rule from `$PLUGIN_ROOT/templates/_shared/rules/parallel-sessions.md` to
`$REPO_ROOT/.claude/rules/parallel-sessions.md` (idempotent: missing→create, identical→skip,
differs→overwrite). See shared partial for full shell command. Issue #155.

Note: Runs before D99. If D99 (via inherited S99) fetches a newer `parallel-sessions.md` from
the baseline, the baseline version wins (acceptable — S99 is canonical).

## Step 3b: Initialize .orchestrator/metrics/ (Deep) (#185)

Deep tier creates both learnings and sessions metrics plus a schema-linking README:

```bash
mkdir -p "$REPO_ROOT/.orchestrator/metrics"
[[ -f "$REPO_ROOT/.orchestrator/metrics/learnings.jsonl" ]] || \
  : > "$REPO_ROOT/.orchestrator/metrics/learnings.jsonl"
[[ -f "$REPO_ROOT/.orchestrator/metrics/sessions.jsonl" ]] || \
  : > "$REPO_ROOT/.orchestrator/metrics/sessions.jsonl"

cat > "$REPO_ROOT/.orchestrator/metrics/README.md" <<'README'
# Metrics

- `learnings.jsonl` — session-scoped learnings (confidence-weighted patterns).
  Managed by the `/evolve` skill.
- `sessions.jsonl` — per-session execution summaries.
  Written by `/close` via session-end.

Schema: https://github.com/Kanevry/session-orchestrator
(see skills/evolve/SKILL.md and skills/session-end/).

**Do NOT gitignore** — these files are project artifacts intended to persist
across sessions and contributors.
README
```

**Idempotent.** Existing files are preserved.

**Gitignore guidance:** same as Standard — `.orchestrator/metrics/*.jsonl` MUST remain tracked.

> Note: Standard tier (Step 3b) only creates `learnings.jsonl`. Deep adds `sessions.jsonl` + the `README.md`. This step is NOT a shared partial because the Deep variant is a superset, not identical.

<!-- @include _shared-template.md#baseline-fetch -->
## Step D99: (Optional) Baseline Fetch — Inherited from Standard

Canonical implementation in [`_shared-template.md#baseline-fetch`](_shared-template.md).

Standard-template Step S99 already executed as part of "Step 1–8: Execute Standard Tier" above.
No additional fetch action is needed here.

If S99 ran successfully, `.claude/rules/*.md` and `.claude/.baseline-fetch.lock` are already written
to `$REPO_ROOT`. These files are included in the Deep commit at Step D8 via the `.claude/` entry
in `BOOTSTRAP_FILES`. If S99 was skipped, rules arrive via the legacy Clank weekly sync MR path.

---

<!-- @include _shared-template.md#agents-scaffold -->
## Step D6.5: .claude/agents/ Scaffold (#189)

Canonical implementation in [`_shared-template.md#agents-scaffold`](_shared-template.md).

Copy 3 opinionated agent templates (`project-discovery`, `project-code-review`,
`project-quality-gate`) into `$REPO_ROOT/.claude/agents/`. Idempotent: skip existing files.
See shared partial for full shell command. Issue #189.

---

<!-- @include _shared-template.md#vault-registration -->
## Step D6.6: Vault-Registration Prompt (Product Repos) (#190)

Canonical implementation in [`_shared-template.md#vault-registration`](_shared-template.md).

Mirrors standard-template Step 5.5. If standard already ran it and the user accepted,
`hasVaultConfig` returns true and this step is a no-op. See shared partial for full detection
script, prompt text, YAML block, and examples. Issue #190.

---

## Step D7: Write bootstrap.lock (Deep)

Write `.orchestrator/bootstrap.lock` **atomically** (mktemp + mv prevents a corrupt lock if the
process is interrupted mid-write):

```bash
_LOCK_TMP=$(mktemp "$REPO_ROOT/.orchestrator/bootstrap.lock.XXXXXX")
cat > "$_LOCK_TMP" << LOCK
# .orchestrator/bootstrap.lock
version: 1
tier: deep
archetype: <CONFIRMED_ARCHETYPE>
timestamp: <current ISO 8601 UTC — e.g., 2026-04-16T09:30:00Z>
source: <claude-init | plugin-template | projects-baseline>
plugin-version: <session-orchestrator plugin version — read from $PLUGIN_ROOT/package.json .version field>
bootstrapped-at: <current ISO 8601 UTC — same value as timestamp; distinct field for age-validation probe>
LOCK
mv "$_LOCK_TMP" "$REPO_ROOT/.orchestrator/bootstrap.lock"
```

Set `source` using the same logic as fast-template Step 5.

---

## Step D8: Git Commit

Stage all created files and commit:

```bash
cd "$REPO_ROOT"
BOOTSTRAP_FILES=(
  CLAUDE.md AGENTS.md .gitignore README.md .orchestrator/bootstrap.lock
  .orchestrator/policy/quality-gates.json
  package.json pyproject.toml tsconfig.json eslint.config.mjs .prettierrc
  .editorconfig src/ tests/ CHANGELOG.md CODEOWNERS
  .gitlab/ .github/ .claude/
)
# Add only the files bootstrap created — no sweeping -u/-A to avoid catching pre-existing files
for _f in "${BOOTSTRAP_FILES[@]}"; do
  [[ -e "$_f" ]] && git add -- "$_f"
done
git commit -m "chore: bootstrap (deep)"
```

The commit message is fixed — do not vary it.

---

## Step D9: Report Created Files

After the commit succeeds, output a concise summary of all files created (Fast + Standard + Deep):

```
Bootstrap (deep, <archetype>) complete. Created:
  CLAUDE.md (or AGENTS.md)             — Session Config
  .gitignore                            — stack-appropriate rules
  README.md                             — expanded with Installation, Usage, Dev
  .editorconfig                         — consistent editor settings
  <manifest>                            — package.json / pyproject.toml
  <tsconfig.json>                       — if JS/TS archetype
  <eslint.config.mjs + .prettierrc>    — if JS/TS archetype
  <tests/sanity.test.ts or equiv>       — sanity test
  .claude/rules/parallel-sessions.md   — vendored PSA rule (issue #155)
  .claude/STATE.md                      — idle placeholder (issue #184)
  CHANGELOG.md                          — initial entry
  CODEOWNERS (or .github/CODEOWNERS)   — placeholder owner
  <.gitlab-ci.yml or .github/workflows/ci.yml> — CI pipeline
  <issue templates>                     — Bug + Feature templates
  <MR/PR template>                      — Default merge/pull request template
  .orchestrator/bootstrap.lock          — version: 1, tier: deep
  .orchestrator/policy/quality-gates.json — test/typecheck/lint commands (issue #183)
  Branch protection on main             — via glab/gh api (result logged above)
Committed: "chore: bootstrap (deep)"
```

Then return control to `SKILL.md` Phase 5.

---

## Not in Deep

The following are intentionally excluded from the Deep tier per the YAGNI-trim in the spec. They add value but are not in the 10-minute-Grundstruktur scope:

- **Renovate / Dependabot** — opt-in via `plan-baseline-path` templates or manual add
- **`docker-compose.yml`** — archetype concern, not tier concern; bring it when the feature needs it
- **Vault-Sync integration** — Meta-Vault is a separate system, integrated via its own skill
- **Pre-commit hooks / husky / lefthook** — personal-preference layer; opt-in manually
