Profile the documentation repository: the argument (text following the docs-profile: trigger)
The argument (text following the docs-profile: trigger) is an optional repo path (default: the current working directory), optionally followed by --inline. The --inline token is passed when document: (Jira mode) invokes this flow inline (its Phase 0 case (c)); it switches this command to inline mode — see Phase 5 step 1, step 2, step 6, and Phase 6.
docs-profile: bootstraps or refreshes the machine-readable docs-profile that document: (Jira mode) consumes. It scans a documentation repository, synthesises a .dev-workflows/docs-profile.yml (and complementary copilot-instructions.md guidance) that conforms to ~/.copilot/installed-plugins/ihudak-copilot-plugins/dev-workflows/skills/_shared/dynatrace-docs/docs-profile-schema.md, then writes the result as a reviewable PR — branch + commit + a drafted PR message. It never pushes or auto-merges.
The command is generic — it works on any docs repo — but produces a richer profile when it detects a multi-space / docstack repo (it then populates cross_space_override and shared_registries; a single-space repo omits them).
It does not re-specify changelog or owners rules. Those are owned by the dynatrace-docs-frontmatter skill (+ ~/.copilot/installed-plugins/ihudak-copilot-plugins/dev-workflows/skills/_shared/dynatrace-docs/changelog-guidelines.md, ~/.copilot/installed-plugins/ihudak-copilot-plugins/dev-workflows/skills/_shared/dynatrace-docs/managed-owners.txt); the profile's frontmatter: fields are pointers only.
For one-off doc edits use direct mode; for Jira-driven feature documentation use document: (Jira mode).
Phase 0 — Resolve and validate the target repo
Resolve the repo path. Take the first token of the argument (text following the docs-profile: trigger) as the target path; if the argument (text following the docs-profile: trigger) is empty, default to the current working directory. Resolve it to an absolute path and record it as <repo>. Treat a --inline token (in any position) as the inline-mode flag, not a path; record inline = true when present.
Validate it is a writeable git work tree:
git -C <repo> rev-parse --is-inside-work-tree must print true. If it errors or prints anything else, stop with the named error: NOT_A_GIT_WORKTREE: <repo> is not inside a git work tree.
test -w <repo> must succeed. If not, stop with the named error: REPO_NOT_WRITEABLE: <repo> is not writeable.
- Resolve and record the repo's git root:
git -C <repo> rev-parse --show-toplevel. All later detection and writes are relative to this root.
Detect docs-repo signals under the git root:
package.json with any doc script (matching *:start, *:build, *:lint, docs:*, prettier),
- a
.docstack/ directory,
- a
.vale.ini file,
- any
*/_content/ directory (e.g. dynatrace/_content, managed/_content),
- any
_snippets/ directory.
If ≥ 1 signal is present → proceed silently to Phase 1.
If 0 signals are present → ask before continuing:
"No documentation-repo signals detected under <repo> (checked: package.json doc scripts, .docstack/, .vale.ini, */_content/, _snippets/). Profile it anyway?"
choices: ["Proceed — I confirm this is a docs repo (Recommended)", "Cancel — point me at a docs repo first", "Other… (describe)"]
Default = Proceed. On Cancel, stop and report.
Phase 1 — Model routing
Load and follow the model-routing policy at
~/.copilot/installed-plugins/ihudak-copilot-plugins/dev-workflows/skills/_shared/model-routing.md, then record:
Profiling is SIGNIFICANT — it is a cross-cutting synthesis of the whole repository whose output (docs-profile.yml) steers every later document: run, so a wrong profile has a large blast radius. State the classification and a one-line reason.
Record a model_routing block modeled on §4 (a profiling command does no implementation/fix edits, so those fields are N/A), resolving each model against the fallback chains:
model_routing:
classification: SIGNIFICANT
reason: "cross-cutting synthesis of the whole docs repo; output steers all later document: runs"
current_model: <the model this orchestrator is running under>
detection_model: <§2.1 detection chain: claude-sonnet-4.6, fallback claude-sonnet-4.5/gpt-5.4>
planning_model: <§2 powerful chain: claude-opus-5 … fallback Sonnet 5/4.6/4.5/GPT-5.4>
review_model: <same as planning_model — conceptually the synthesis_model; the synthesis step runs on the §2 Opus chain>
opus_available: true | false
notes: <any §2.1/§2 degradation, e.g. "Opus unavailable; synthesis fell back to claude-sonnet-4.6">
The detection phase (Phase 2) pins its subagent to detection_model (the §2.1 chain) via the task tool's model: override — never the session model. The synthesize phase (Phase 3) pins to planning_model (the §2 Opus chain). Announce any fallback now and again in Phase 6.
Phase 2 — Detect (Sonnet-tier)
Dispatch a read-only detection subagent pinned to the §2.1 mid-tier chain via the task tool's model: override — claude-sonnet-4.6, fallback claude-sonnet-4.5/gpt-5.4; record the model actually used as detection_model in the model_routing block. Detection is mechanical repo scanning, so it must NOT inherit the session model (an Opus session would otherwise burn Opus on a cheap step, per §2.1).
→ task(agent_type: "general-purpose", model: <detection_model — §2.1 detection chain: claude-sonnet-4.6, fallback claude-sonnet-4.5/gpt-5.4>):
"Read-only detection scan for a docs-profile. Do NOT write or edit any file — return a structured detection report only.
repo_root: <resolved git root from Phase 0>
Gather and report, each with the file path + a short verbatim excerpt as evidence:
- package.json scripts — every script whose name matches
*:start, *:lint, *:build, docs:*, format/prettier. For each *:start script, extract the dev-server port and base path (grep the script and any referenced config — e.g. --port, PORT=, a base/basePath in a docusaurus/mkdocs/eleventy/vitepress config). Note whether two *:start servers can run concurrently (distinct ports → concurrent; shared port / single server → sequential).
- Cross-space override manifest — presence and shape of
managed/docstack.jsonc (or any docstack.jsonc): the allowlist block that pulls ../dynatrace/_content/... pages, and whether it has an ignore list. Quote the allowlist + ignore keys.
- Shared registries — presence of
schema-ids.yml and schema-mappings.yml (search the tree); report their paths and whether both exist.
- Templating tokens — grep the content roots for:
{{tag kind='latest'}} (gen3/Latest marker), ::app-settings:: (gen3 settings breadcrumb), and {{#if project= (project conditionals — list the distinct project values seen, e.g. saas/managed/classic).
- Content + snippet roots — every
*/_content and every */_snippets directory (e.g. dynatrace/_content, dynatrace/_snippets, managed/_content, managed/_snippets). This determines the spaces[] list: one rendered space per content root.
- Branch-naming + internal-link conventions — read CONTRIBUTING.md, CONTRIBUTION.md, README.md, DOCUMENTATION-GUIDELINES.md, and .github/copilot-instructions.md at the repo root (and
.github/). Quote any documented branch-naming pattern (e.g. <initials>/<JIRA-KEY>-<slug>) and any internal-link convention (e.g. [text](<postid>) where postid comes from target frontmatter).
- Image policy — any documented rule for screenshots/images (CDN-hosted vs committed binaries); quote the source.
- Prerequisites — anything a dev server needs before
*:start boots (e.g. a .docstack toolchain / shim, an axios version pin, an env var); quote the source.
- Announcement pages — hand-authored destination pages inside an otherwise automation-owned tree (e.g. a release-notes / what's-new tree). Detection signal: a page under such a tree whose frontmatter does NOT carry
meta.content-type: release-notes (absent, or any other value) AND whose git log shows human PR commits rather than automation. For each match, record its postid (frontmatter postid:), its repo-relative path, and a proposed kinds list inferred from the page title and headings (e.g. an "End-of-life announcements" page → [deprecation, end-of-life, shutdown, sunset]). Report announcement_pages: [] explicitly when none are found.
Return one section per item above. For anything not found, say not found explicitly — do not guess. End with a one-paragraph summary: single-space vs multi-space, and whether this looks like a docstack repo."
Wait for the detection report. If the agent returns nothing usable or fails, gather the same facts yourself via Glob/Grep/Read (read-only) before Phase 3 — but still record detection_model as the chain you attempted.
Phase 3 — Synthesize the draft profile (Opus)
On the §2 powerful chain (planning_model), turn the detection report into a draft docs-profile.yml. This synthesis is the SIGNIFICANT reasoning step, so it runs on the strongest available reasoning model (Opus), pinned via the task tool's model: override — not the §2.1 detection chain.
→ task(agent_type: "general-purpose", model: <planning_model — §2 chain: claude-opus-5, fallback per §2>):
"Synthesise a docs-profile from a detection report. This is a planning/synthesis task, not a code change — return the drafted YAML + drafted copilot-instructions.md additions, nothing else; do not write files.
Schema (the draft MUST conform exactly): ~/.copilot/installed-plugins/ihudak-copilot-plugins/dev-workflows/skills/_shared/dynatrace-docs/docs-profile-schema.md
Detection report: [paste the full Phase 2 report]
model_routing: [paste the Phase 1 block]
Rules:
- Emit
schema_version: 1 and one spaces[] entry per detected content root (id, content_root, snippet_root, base_path). spaces[] is required and non-empty.
dev_servers: one servers[] entry per *:start script with its command, port, base_path; set concurrent: false unless detection proved two servers can run at once.
commands: lint, format, and any commit-hook chain detected.
- Multi-space / docstack only: include
cross_space_override (manifest path + the last-write-wins shadowing mechanism + the ignore-to-win rule) and shared_registries (the schema-ids.yml / schema-mappings.yml lock-step rule). Single-space repo: OMIT both.
tokens: only the markers detection actually found (latest_tag, gen3_settings_breadcrumb, project_conditionals).
internal_links.convention, branch_naming.pattern, images.policy, prerequisites[]: fill from detection; leave a field out rather than inventing it.
announcement_pages[]: one entry per page found by detection item 9 (Announcement pages), each {postid, path, kinds}. Emit announcement_pages: [] explicitly when detection found none — do not omit the key.
commands.per_space: — when package.json (or the repo's task runner) exposes per-space lint / build / format scripts whose names correspond to entries in spaces[] (e.g. dynatrace:lint + managed:lint for spaces saas + managed), record them under commands.per_space.<space id>. Map the script name to the space id by the space's content_root (dynatrace/_content ⇒ script prefix dynatrace), never by guessing. Omit per_space entirely for a single-space repo, or when only whole-repo scripts exist.
frontmatter: is POINTERS ONLY — set owned_by_skill: dynatrace-docs-frontmatter, changelog_guidelines: ~/.copilot/installed-plugins/ihudak-copilot-plugins/dev-workflows/skills/_shared/dynatrace-docs/changelog-guidelines.md, managed_owners: ~/.copilot/installed-plugins/ihudak-copilot-plugins/dev-workflows/skills/_shared/dynatrace-docs/managed-owners.txt. NEVER copy any changelog or owners rule text into the profile.
- Mark every field as
detected (grounded in the report) or needs-confirmation (inferred / not found) so the orchestrator knows what to ask in Phase 4.
- Separately, draft minimal complementary copilot-instructions.md additions ONLY for conventions not already covered by the dynatrace-docs-frontmatter skill or its reminder hook (e.g. the cross-space shadowing gotcha, the shared-registry lock-step rule, dev-server sequencing). Do NOT restate changelog/owners — defer to the skill."
Wait for the synthesis. Hold the drafted docs-profile.yml and the drafted copilot-instructions.md additions for Phase 4. If Opus was unavailable and the synthesis fell back to Sonnet, note it in model_routing.notes and carry it to Phase 6.
Phase 4 — Confirm and fill gaps
Rule: Ask, don't guess. For every field the synthesis marked needs-confirmation — and anything detection could not settle — ask the user. Use choices arrays; the last choice is always "Other… (describe)"; the recommended default is first and labelled "(Recommended)". Group related fields into one question where possible.
Typical gaps:
- Exact build / start command when a script was ambiguous:
choices: ["Use detected `<cmd>` (Recommended)", "Enter the correct command", "Leave unset", "Other… (describe)"]
- Prerequisites such as the
.docstack shim (e.g. an axios>=1.16 pin) that must be in place before *:start boots:choices: ["Record detected prerequisite(s) (Recommended)", "Add a prerequisite I'll describe", "No prerequisites", "Other… (describe)"]
- Ambiguous space mapping (a content root with no obvious
id / base_path):choices: ["Accept proposed space mapping (Recommended)", "Edit a space's id/base_path", "Drop this space", "Other… (describe)"]
- Branch-naming convention when none was documented (drives Phase 5):
choices: ["Use repo convention if detected, else `<prefix>/NOISSUE-docs-profile` (Recommended)", "Enter a different pattern", "Other… (describe)"]
Idempotent refresh. Before writing, check whether <repo-root>/.dev-workflows/docs-profile.yml already exists:
- Exists → show a field-level diff (existing value → new value, per key) and confirm:
"A docs-profile already exists. Apply these field-level changes?"
choices: ["Apply the diff — overwrite changed fields (Recommended)", "Keep existing, write nothing", "Edit specific fields first (you'll be prompted)", "Other… (describe)"]
Do not overwrite without this confirmation.
- Absent → bootstrap: proceed to Phase 5 with the confirmed draft.
Record the final, confirmed docs-profile.yml and copilot-instructions.md additions, and tag each field detected vs user-supplied for the Phase 6 report.
Phase 5 — Write as a reviewable PR
Produce a reviewable PR in the target repo (never the plugin). Never push or auto-merge unless the user explicitly asks.
Resolve the branch name. Inline mode (--inline): skip the prompt and the confirmation entirely — use the deterministic name dev-workflows/docs-profile-bootstrap; document: (Jira mode) Phase 6.2 renames it to the docs-branch convention. Standalone (default):
- If the repo documents a branch-naming convention (detected in Phase 2 / confirmed in Phase 4), fill its placeholders and use it.
- If the convention has an identity placeholder, fill it from the §2 ladder in
~/.copilot/installed-plugins/ihudak-copilot-plugins/dev-workflows/skills/_shared/branch-naming.md ($GIT_USER_INITIALS → git config user.initials → inference from existing branches → the §2.5 prompt); its issue-key segment takes the documented no-issue literal, since profiling has no ticket.
- Else (no convention documented, §1.4) use
<prefix>/NOISSUE-docs-profile, where <prefix> comes from the same §2 ladder with fallback docs/. If the ladder yields nothing, run its §2.5 escalation:"I couldn't infer a branch prefix from $GIT_USER_INITIALS, `git config user.initials`, or existing branches. This workflow's default is `docs/`. What prefix should I use?"
choices: ["Use `docs/` (default for this workflow)", "Use my initials — I'll enter them next", "Other… (describe)"]
Always confirm the final name (initials/slugs are subjective):
choices: ["Use proposed branch `<name>` (Recommended)", "Edit the name", "Other… (describe)"]
Prepare the working tree. git -C <repo-root> status --porcelain; if non-empty:
choices: ["Stash changes and continue (Recommended)", "Proceed anyway — pre-existing changes will appear in the diff", "Cancel", "Other… (describe)"]
Then base the branch on the repo's default branch so the profile PR is cut from a clean base: resolve the base (git -C <repo-root> symbolic-ref --short refs/remotes/origin/HEAD; fall back to main, then master) and run git -C <repo-root> switch <base> && git -C <repo-root> pull --ff-only (the clean-tree check above already ran; if the fast-forward pull fails, offer the same stash/proceed/cancel choices). Then create the branch: git -C <repo-root> switch -c <name> (or git -C <repo-root> switch <name> if it already exists).
Write the profile. Create <repo-root>/.dev-workflows/ if absent, then write the confirmed .dev-workflows/docs-profile.yml. It MUST conform to ~/.copilot/installed-plugins/ihudak-copilot-plugins/dev-workflows/skills/_shared/dynatrace-docs/docs-profile-schema.md. Apply the confirmed complementary copilot-instructions.md additions to the repo's .github/copilot-instructions.md (create the file if absent) — minimal, additive, scoped edits only; never restate changelog/owners rules owned by the dynatrace-docs-frontmatter skill.
Format / lint. If the repo has a formatter or linter (the format/lint commands captured in the profile), run it on the written files; fix anything it flags on those files. Skip silently if none is configured.
Commit. git -C <repo-root> add .dev-workflows/docs-profile.yml .github/copilot-instructions.md (only the files this command wrote), then commit:
git -C <repo-root> commit -m "docs: add/refresh .dev-workflows/docs-profile.yml"
Draft the PR message. Inline mode (--inline): skip this step — control returns to document: (Jira mode), which owns the single PR draft (its Phase 8.5). Standalone: Detect the host (git -C <repo-root> remote get-url origin) and draft a copy-paste-ready PR title + body for Bitbucket or GitHub (whichever the remote indicates). Title e.g. docs: bootstrap docs-profile for document:; body summarising the profile (spaces, dev-servers, cross-space override, tokens, branch-naming, images, prerequisites) and the copilot-instructions.md additions. Do not push, do not open the PR via any CLI — present the branch name + the drafted message for the user to push and open themselves.
Phase 6 — Final report
Inline mode (--inline): skip this report — control returns to document: (Jira mode), which produces the consolidated report (its Phase 9). The rest of this section is the standalone report.
Output a structured report — do NOT ask any closing confirmation:
## Docs-profile Report
### Classification
SIGNIFICANT — cross-cutting synthesis of the whole docs repo; output steers all later document: runs
### Target repo
<resolved git root> (single-space | multi-space / docstack)
### Profile written
<repo-root>/.dev-workflows/docs-profile.yml (bootstrapped | refreshed)
### Fields: detected vs user-supplied
- detected: [spaces, dev_servers, commands, cross_space_override, shared_registries, tokens, internal_links, announcement_pages, branch_naming, images, prerequisites — list those that were detected]
- user-supplied: [list the fields confirmed/filled in Phase 4]
- omitted: [e.g. "cross_space_override + shared_registries — single-space repo"]
- frontmatter: pointers only → dynatrace-docs-frontmatter skill (+ changelog-guidelines.md, managed-owners.txt); changelog/owners NOT re-specified
### copilot-instructions.md additions
- [what was added to the repo's copilot-instructions.md, or "none — all conventions covered by the dynatrace-docs-frontmatter skill"]
### Branch
<branch name created>
### PR draft (copy-paste)
**Title:** <title>
<body>
### Model Routing
- Classification: SIGNIFICANT
- Detection model (§2.1): <detection_model>
- Synthesis model (§2): <planning_model>
- Opus available: <true | false>
- Notes: <any §2.1/§2 fallback that occurred, or "none">
### Git state
Branch <name> created with 1 commit on <repo-root>. NOT pushed and NOT merged — push and open the PR yourself when ready.
### Assumptions & limitations
- [list any]
Invariants (always enforced)
- ALWAYS validate the target is a writeable git work tree (Phase 0); stop with a named error if not
- ALWAYS pin detection to the §2.1 detection chain via the
task model: override — never inherit the session model — and record detection_model
- ALWAYS run the synthesis on the §2 powerful (Opus) chain via the
task model: override
- ALWAYS conform the written profile to
~/.copilot/installed-plugins/ihudak-copilot-plugins/dev-workflows/skills/_shared/dynatrace-docs/docs-profile-schema.md
- ALWAYS treat
frontmatter: as pointers to the dynatrace-docs-frontmatter skill; NEVER copy changelog/owners rules into the profile
- OMIT
cross_space_override and shared_registries for a single-space repo; include them only when a multi-space / docstack repo is detected
- ALWAYS show a field-level diff and confirm before overwriting an existing
.dev-workflows/docs-profile.yml (idempotent refresh)
- ALWAYS write the profile to
.dev-workflows/docs-profile.yml in the TARGET repo — never the plugin
- NEVER push or auto-merge — output a reviewable PR (branch + commit + drafted PR message) for the user to push
- ALWAYS use
choices arrays for decision points; recommended default first and labelled "(Recommended)"; last choice always "Other… (describe)"
- ALWAYS reference plugin paths with
~/.copilot/installed-plugins/ihudak-copilot-plugins/dev-workflows
- ALWAYS produce the Phase 6 report as the final output, noting any §2.1/§2 model fallback
1---2name: docs-profile3description: Scan a documentation repository and write/refresh a machine-readable docs-profile (.dev-workflows/docs-profile.yml) plus complementary copilot-instructions.md guidance, as a reviewable PR. Captures spaces, dev-servers, cross-space override/shadowing, shared registries, gen3/Classic tokens, links, announcement pages, branch-naming, images, and prerequisites; defers changelog/owners to the dynatrace-docs-frontmatter skill. Bootstraps or refreshes the profile that document: consumes. Activated when the user prompt starts with "docs-profile:".4---56Profile the documentation repository: the argument (text following the `docs-profile:` trigger)78The argument (text following the `docs-profile:` trigger) is an optional repo path (default: the current working directory), optionally followed by `--inline`. The `--inline` token is passed when `document:` (Jira mode) invokes this flow inline (its Phase 0 case (c)); it switches this command to **inline mode** — see Phase 5 step 1, step 2, step 6, and Phase 6.910`docs-profile:` **bootstraps or refreshes** the machine-readable docs-profile that `document:` (Jira mode) consumes. It scans a documentation repository, synthesises a `.dev-workflows/docs-profile.yml` (and complementary copilot-instructions.md guidance) that conforms to `~/.copilot/installed-plugins/ihudak-copilot-plugins/dev-workflows/skills/_shared/dynatrace-docs/docs-profile-schema.md`, then writes the result as a **reviewable PR** — branch + commit + a drafted PR message. It never pushes or auto-merges.1112The command is **generic** — it works on any docs repo — but produces a richer profile when it detects a multi-space / docstack repo (it then populates `cross_space_override` and `shared_registries`; a single-space repo omits them).1314It does **not** re-specify changelog or owners rules. Those are owned by the `dynatrace-docs-frontmatter` skill (+ `~/.copilot/installed-plugins/ihudak-copilot-plugins/dev-workflows/skills/_shared/dynatrace-docs/changelog-guidelines.md`, `~/.copilot/installed-plugins/ihudak-copilot-plugins/dev-workflows/skills/_shared/dynatrace-docs/managed-owners.txt`); the profile's `frontmatter:` fields are **pointers only**.1516For one-off doc edits use direct mode; for Jira-driven feature documentation use `document:` (Jira mode).1718---1920## Phase 0 — Resolve and validate the target repo21221. **Resolve the repo path.** Take the first token of the argument (text following the `docs-profile:` trigger) as the target path; if the argument (text following the `docs-profile:` trigger) is empty, default to the current working directory. Resolve it to an absolute path and record it as `<repo>`. Treat a `--inline` token (in any position) as the inline-mode flag, not a path; record `inline = true` when present.23242. **Validate it is a writeable git work tree:**25 - `git -C <repo> rev-parse --is-inside-work-tree` must print `true`. If it errors or prints anything else, stop with the named error: `NOT_A_GIT_WORKTREE: <repo> is not inside a git work tree.`26 - `test -w <repo>` must succeed. If not, stop with the named error: `REPO_NOT_WRITEABLE: <repo> is not writeable.`27 - Resolve and record the repo's git root: `git -C <repo> rev-parse --show-toplevel`. All later detection and writes are relative to this root.28293. **Detect docs-repo signals** under the git root:30 - `package.json` with any doc script (matching `*:start`, `*:build`, `*:lint`, `docs:*`, `prettier`),31 - a `.docstack/` directory,32 - a `.vale.ini` file,33 - any `*/_content/` directory (e.g. `dynatrace/_content`, `managed/_content`),34 - any `_snippets/` directory.3536 If **≥ 1** signal is present → proceed silently to Phase 1.37 If **0** signals are present → ask before continuing:38 ```39 "No documentation-repo signals detected under <repo> (checked: package.json doc scripts, .docstack/, .vale.ini, */_content/, _snippets/). Profile it anyway?"40 choices: ["Proceed — I confirm this is a docs repo (Recommended)", "Cancel — point me at a docs repo first", "Other… (describe)"]41 ```42 Default = Proceed. On Cancel, stop and report.4344---4546## Phase 1 — Model routing4748Load and follow the model-routing policy at49`~/.copilot/installed-plugins/ihudak-copilot-plugins/dev-workflows/skills/_shared/model-routing.md`, then record:5051Profiling is **SIGNIFICANT** — it is a cross-cutting synthesis of the whole repository whose output (`docs-profile.yml`) steers every later `document:` run, so a wrong profile has a large blast radius. State the classification and a one-line reason.5253Record a `model_routing` block modeled on §4 (a profiling command does no implementation/fix edits, so those fields are N/A), resolving each model against the fallback chains:5455```yaml56model_routing:57 classification: SIGNIFICANT58 reason: "cross-cutting synthesis of the whole docs repo; output steers all later document: runs"59 current_model: <the model this orchestrator is running under>60 detection_model: <§2.1 detection chain: claude-sonnet-4.6, fallback claude-sonnet-4.5/gpt-5.4>61 planning_model: <§2 powerful chain: claude-opus-5 … fallback Sonnet 5/4.6/4.5/GPT-5.4>62 review_model: <same as planning_model — conceptually the synthesis_model; the synthesis step runs on the §2 Opus chain>63 opus_available: true | false64 notes: <any §2.1/§2 degradation, e.g. "Opus unavailable; synthesis fell back to claude-sonnet-4.6">65```6667The detection phase (Phase 2) pins its subagent to `detection_model` (the §2.1 chain) via the `task` tool's `model:` override — never the session model. The synthesize phase (Phase 3) pins to `planning_model` (the §2 Opus chain). Announce any fallback now and again in Phase 6.6869---7071## Phase 2 — Detect (Sonnet-tier)7273Dispatch a **read-only** detection subagent **pinned to the §2.1 mid-tier chain** via the `task` tool's `model:` override — `claude-sonnet-4.6`, fallback `claude-sonnet-4.5`/`gpt-5.4`; record the model actually used as `detection_model` in the `model_routing` block. Detection is mechanical repo scanning, so it must NOT inherit the session model (an Opus session would otherwise burn Opus on a cheap step, per §2.1).7475→ task(agent_type: "general-purpose", model: `<detection_model — §2.1 detection chain: claude-sonnet-4.6, fallback claude-sonnet-4.5/gpt-5.4>`):76 > "Read-only detection scan for a docs-profile. Do NOT write or edit any file — return a structured detection report only.77 >78 > repo_root: <resolved git root from Phase 0>79 >80 > Gather and report, each with the file path + a short verbatim excerpt as evidence:81 >82 > 1. **package.json scripts** — every script whose name matches `*:start`, `*:lint`, `*:build`, `docs:*`, `format`/`prettier`. For each `*:start` script, extract the dev-server port and base path (grep the script and any referenced config — e.g. `--port`, `PORT=`, a `base`/`basePath` in a docusaurus/mkdocs/eleventy/vitepress config). Note whether two `*:start` servers can run concurrently (distinct ports → concurrent; shared port / single server → sequential).83 > 2. **Cross-space override manifest** — presence and shape of `managed/docstack.jsonc` (or any `docstack.jsonc`): the allowlist block that pulls `../dynatrace/_content/...` pages, and whether it has an `ignore` list. Quote the allowlist + ignore keys.84 > 3. **Shared registries** — presence of `schema-ids.yml` and `schema-mappings.yml` (search the tree); report their paths and whether both exist.85 > 4. **Templating tokens** — grep the content roots for: `{{tag kind='latest'}}` (gen3/Latest marker), `::app-settings::` (gen3 settings breadcrumb), and `{{#if project=` (project conditionals — list the distinct project values seen, e.g. saas/managed/classic).86 > 5. **Content + snippet roots** — every `*/_content` and every `*/_snippets` directory (e.g. `dynatrace/_content`, `dynatrace/_snippets`, `managed/_content`, `managed/_snippets`). This determines the `spaces[]` list: one rendered space per content root.87 > 6. **Branch-naming + internal-link conventions** — read CONTRIBUTING.md, CONTRIBUTION.md, README.md, DOCUMENTATION-GUIDELINES.md, and .github/copilot-instructions.md at the repo root (and `.github/`). Quote any documented branch-naming pattern (e.g. `<initials>/<JIRA-KEY>-<slug>`) and any internal-link convention (e.g. `[text](<postid>)` where postid comes from target frontmatter).88 > 7. **Image policy** — any documented rule for screenshots/images (CDN-hosted vs committed binaries); quote the source.89 > 8. **Prerequisites** — anything a dev server needs before `*:start` boots (e.g. a `.docstack` toolchain / shim, an axios version pin, an env var); quote the source.90 > 9. **Announcement pages** — hand-authored destination pages inside an otherwise automation-owned tree (e.g. a release-notes / what's-new tree). Detection signal: a page under such a tree whose frontmatter does NOT carry `meta.content-type: release-notes` (absent, or any other value) AND whose `git log` shows human PR commits rather than automation. For each match, record its `postid` (frontmatter `postid:`), its repo-relative `path`, and a proposed `kinds` list inferred from the page title and headings (e.g. an "End-of-life announcements" page → `[deprecation, end-of-life, shutdown, sunset]`). Report `announcement_pages: []` explicitly when none are found.91 >92 > Return one section per item above. For anything not found, say `not found` explicitly — do not guess. End with a one-paragraph summary: single-space vs multi-space, and whether this looks like a docstack repo."9394**Wait for the detection report.** If the agent returns nothing usable or fails, gather the same facts yourself via Glob/Grep/Read (read-only) before Phase 3 — but still record `detection_model` as the chain you attempted.9596---9798## Phase 3 — Synthesize the draft profile (Opus)99100On the §2 powerful chain (`planning_model`), turn the detection report into a draft `docs-profile.yml`. This synthesis is the SIGNIFICANT reasoning step, so it runs on the strongest available reasoning model (Opus), pinned via the `task` tool's `model:` override — not the §2.1 detection chain.101102→ task(agent_type: "general-purpose", model: `<planning_model — §2 chain: claude-opus-5, fallback per §2>`):103 > "Synthesise a docs-profile from a detection report. This is a planning/synthesis task, not a code change — return the drafted YAML + drafted copilot-instructions.md additions, nothing else; do not write files.104 >105 > Schema (the draft MUST conform exactly): `~/.copilot/installed-plugins/ihudak-copilot-plugins/dev-workflows/skills/_shared/dynatrace-docs/docs-profile-schema.md`106 > Detection report: [paste the full Phase 2 report]107 > model_routing: [paste the Phase 1 block]108 >109 > Rules:110 > - Emit `schema_version: 1` and one `spaces[]` entry per detected content root (`id`, `content_root`, `snippet_root`, `base_path`). `spaces[]` is required and non-empty.111 > - `dev_servers`: one `servers[]` entry per `*:start` script with its `command`, `port`, `base_path`; set `concurrent: false` unless detection proved two servers can run at once.112 > - `commands`: `lint`, `format`, and any commit-hook chain detected.113 > - **Multi-space / docstack only:** include `cross_space_override` (manifest path + the last-write-wins shadowing mechanism + the `ignore`-to-win rule) and `shared_registries` (the `schema-ids.yml` / `schema-mappings.yml` lock-step rule). **Single-space repo:** OMIT both.114 > - `tokens`: only the markers detection actually found (`latest_tag`, `gen3_settings_breadcrumb`, `project_conditionals`).115 > - `internal_links.convention`, `branch_naming.pattern`, `images.policy`, `prerequisites[]`: fill from detection; leave a field out rather than inventing it.116 > - `announcement_pages[]`: one entry per page found by detection item 9 (Announcement pages), each `{postid, path, kinds}`. Emit `announcement_pages: []` explicitly when detection found none — do not omit the key.117 > - `commands.per_space:` — when `package.json` (or the repo's task runner) exposes **per-space** lint / build / format scripts whose names correspond to entries in `spaces[]` (e.g. `dynatrace:lint` + `managed:lint` for spaces `saas` + `managed`), record them under `commands.per_space.<space id>`. Map the script name to the space id by the space's `content_root` (`dynatrace/_content` ⇒ script prefix `dynatrace`), never by guessing. Omit `per_space` entirely for a single-space repo, or when only whole-repo scripts exist.118 > - `frontmatter:` is **POINTERS ONLY** — set `owned_by_skill: dynatrace-docs-frontmatter`, `changelog_guidelines: ~/.copilot/installed-plugins/ihudak-copilot-plugins/dev-workflows/skills/_shared/dynatrace-docs/changelog-guidelines.md`, `managed_owners: ~/.copilot/installed-plugins/ihudak-copilot-plugins/dev-workflows/skills/_shared/dynatrace-docs/managed-owners.txt`. NEVER copy any changelog or owners rule text into the profile.119 > - Mark every field as `detected` (grounded in the report) or `needs-confirmation` (inferred / not found) so the orchestrator knows what to ask in Phase 4.120 > - Separately, draft minimal complementary **copilot-instructions.md additions** ONLY for conventions not already covered by the dynatrace-docs-frontmatter skill or its reminder hook (e.g. the cross-space shadowing gotcha, the shared-registry lock-step rule, dev-server sequencing). Do NOT restate changelog/owners — defer to the skill."121122**Wait for the synthesis.** Hold the drafted `docs-profile.yml` and the drafted copilot-instructions.md additions for Phase 4. If Opus was unavailable and the synthesis fell back to Sonnet, note it in `model_routing.notes` and carry it to Phase 6.123124---125126## Phase 4 — Confirm and fill gaps127128**Rule: Ask, don't guess.** For every field the synthesis marked `needs-confirmation` — and anything detection could not settle — ask the user. Use `choices` arrays; the **last** choice is always `"Other… (describe)"`; the recommended default is first and labelled `"(Recommended)"`. Group related fields into one question where possible.129130Typical gaps:131132- **Exact build / start command** when a script was ambiguous:133 ```134 choices: ["Use detected `<cmd>` (Recommended)", "Enter the correct command", "Leave unset", "Other… (describe)"]135 ```136- **Prerequisites** such as the `.docstack` shim (e.g. an axios>=1.16 pin) that must be in place before `*:start` boots:137 ```138 choices: ["Record detected prerequisite(s) (Recommended)", "Add a prerequisite I'll describe", "No prerequisites", "Other… (describe)"]139 ```140- **Ambiguous space mapping** (a content root with no obvious `id` / `base_path`):141 ```142 choices: ["Accept proposed space mapping (Recommended)", "Edit a space's id/base_path", "Drop this space", "Other… (describe)"]143 ```144- **Branch-naming convention** when none was documented (drives Phase 5):145 ```146 choices: ["Use repo convention if detected, else `<prefix>/NOISSUE-docs-profile` (Recommended)", "Enter a different pattern", "Other… (describe)"]147 ```148149**Idempotent refresh.** Before writing, check whether `<repo-root>/.dev-workflows/docs-profile.yml` already exists:150- **Exists** → show a **field-level diff** (existing value → new value, per key) and confirm:151 ```152 "A docs-profile already exists. Apply these field-level changes?"153 choices: ["Apply the diff — overwrite changed fields (Recommended)", "Keep existing, write nothing", "Edit specific fields first (you'll be prompted)", "Other… (describe)"]154 ```155 Do not overwrite without this confirmation.156- **Absent** → bootstrap: proceed to Phase 5 with the confirmed draft.157158Record the final, confirmed `docs-profile.yml` and copilot-instructions.md additions, and tag each field `detected` vs `user-supplied` for the Phase 6 report.159160---161162## Phase 5 — Write as a reviewable PR163164Produce a reviewable PR in the **target repo** (never the plugin). **Never push or auto-merge** unless the user explicitly asks.1651661. **Resolve the branch name.** **Inline mode** (`--inline`): skip the prompt and the confirmation entirely — use the deterministic name `dev-workflows/docs-profile-bootstrap`; `document:` (Jira mode) Phase 6.2 renames it to the docs-branch convention. **Standalone** (default):167 - If the repo documents a branch-naming convention (detected in Phase 2 / confirmed in Phase 4), fill its placeholders and use it.168 - If the convention has an **identity** placeholder, fill it from the §2 ladder in `~/.copilot/installed-plugins/ihudak-copilot-plugins/dev-workflows/skills/_shared/branch-naming.md` (`$GIT_USER_INITIALS` → `git config user.initials` → inference from existing branches → the §2.5 prompt); its issue-key segment takes the documented no-issue literal, since profiling has no ticket.169 - Else (no convention documented, §1.4) use `<prefix>/NOISSUE-docs-profile`, where `<prefix>` comes from the same §2 ladder with fallback `docs/`. If the ladder yields nothing, run its §2.5 escalation:170 ```171 "I couldn't infer a branch prefix from $GIT_USER_INITIALS, `git config user.initials`, or existing branches. This workflow's default is `docs/`. What prefix should I use?"172 choices: ["Use `docs/` (default for this workflow)", "Use my initials — I'll enter them next", "Other… (describe)"]173 ```174 Always confirm the final name (initials/slugs are subjective):175 ```176 choices: ["Use proposed branch `<name>` (Recommended)", "Edit the name", "Other… (describe)"]177 ```1781792. **Prepare the working tree.** `git -C <repo-root> status --porcelain`; if non-empty:180 ```181 choices: ["Stash changes and continue (Recommended)", "Proceed anyway — pre-existing changes will appear in the diff", "Cancel", "Other… (describe)"]182 ```183 Then base the branch on the repo's default branch so the profile PR is cut from a clean base: resolve the base (`git -C <repo-root> symbolic-ref --short refs/remotes/origin/HEAD`; fall back to `main`, then `master`) and run `git -C <repo-root> switch <base> && git -C <repo-root> pull --ff-only` (the clean-tree check above already ran; if the fast-forward pull fails, offer the same stash/proceed/cancel choices). Then create the branch: `git -C <repo-root> switch -c <name>` (or `git -C <repo-root> switch <name>` if it already exists).1841853. **Write the profile.** Create `<repo-root>/.dev-workflows/` if absent, then write the confirmed `.dev-workflows/docs-profile.yml`. It MUST conform to `~/.copilot/installed-plugins/ihudak-copilot-plugins/dev-workflows/skills/_shared/dynatrace-docs/docs-profile-schema.md`. Apply the confirmed complementary copilot-instructions.md additions to the repo's `.github/copilot-instructions.md` (create the file if absent) — minimal, additive, scoped edits only; never restate changelog/owners rules owned by the dynatrace-docs-frontmatter skill.1861874. **Format / lint.** If the repo has a formatter or linter (the `format`/`lint` commands captured in the profile), run it on the written files; fix anything it flags on those files. Skip silently if none is configured.1881895. **Commit.** `git -C <repo-root> add .dev-workflows/docs-profile.yml .github/copilot-instructions.md` (only the files this command wrote), then commit:190 ```191 git -C <repo-root> commit -m "docs: add/refresh .dev-workflows/docs-profile.yml"192 ```1931946. **Draft the PR message.** **Inline mode** (`--inline`): skip this step — control returns to `document:` (Jira mode), which owns the single PR draft (its Phase 8.5). **Standalone:** Detect the host (`git -C <repo-root> remote get-url origin`) and draft a copy-paste-ready PR title + body for Bitbucket or GitHub (whichever the remote indicates). Title e.g. `docs: bootstrap docs-profile for document:`; body summarising the profile (spaces, dev-servers, cross-space override, tokens, branch-naming, images, prerequisites) and the copilot-instructions.md additions. **Do not push, do not open the PR via any CLI** — present the branch name + the drafted message for the user to push and open themselves.195196---197198## Phase 6 — Final report199200**Inline mode** (`--inline`): skip this report — control returns to `document:` (Jira mode), which produces the consolidated report (its Phase 9). The rest of this section is the standalone report.201202Output a structured report — do NOT ask any closing confirmation:203204```205## Docs-profile Report206207### Classification208SIGNIFICANT — cross-cutting synthesis of the whole docs repo; output steers all later document: runs209210### Target repo211<resolved git root> (single-space | multi-space / docstack)212213### Profile written214<repo-root>/.dev-workflows/docs-profile.yml (bootstrapped | refreshed)215216### Fields: detected vs user-supplied217- detected: [spaces, dev_servers, commands, cross_space_override, shared_registries, tokens, internal_links, announcement_pages, branch_naming, images, prerequisites — list those that were detected]218- user-supplied: [list the fields confirmed/filled in Phase 4]219- omitted: [e.g. "cross_space_override + shared_registries — single-space repo"]220- frontmatter: pointers only → dynatrace-docs-frontmatter skill (+ changelog-guidelines.md, managed-owners.txt); changelog/owners NOT re-specified221222### copilot-instructions.md additions223- [what was added to the repo's copilot-instructions.md, or "none — all conventions covered by the dynatrace-docs-frontmatter skill"]224225### Branch226<branch name created>227228### PR draft (copy-paste)229**Title:** <title>230231<body>232233### Model Routing234- Classification: SIGNIFICANT235- Detection model (§2.1): <detection_model>236- Synthesis model (§2): <planning_model>237- Opus available: <true | false>238- Notes: <any §2.1/§2 fallback that occurred, or "none">239240### Git state241Branch <name> created with 1 commit on <repo-root>. NOT pushed and NOT merged — push and open the PR yourself when ready.242243### Assumptions & limitations244- [list any]245```246247---248249## Invariants (always enforced)250251- ALWAYS validate the target is a writeable git work tree (Phase 0); stop with a named error if not252- ALWAYS pin detection to the §2.1 detection chain via the `task` `model:` override — never inherit the session model — and record `detection_model`253- ALWAYS run the synthesis on the §2 powerful (Opus) chain via the `task` `model:` override254- ALWAYS conform the written profile to `~/.copilot/installed-plugins/ihudak-copilot-plugins/dev-workflows/skills/_shared/dynatrace-docs/docs-profile-schema.md`255- ALWAYS treat `frontmatter:` as pointers to the dynatrace-docs-frontmatter skill; NEVER copy changelog/owners rules into the profile256- OMIT `cross_space_override` and `shared_registries` for a single-space repo; include them only when a multi-space / docstack repo is detected257- ALWAYS show a field-level diff and confirm before overwriting an existing `.dev-workflows/docs-profile.yml` (idempotent refresh)258- ALWAYS write the profile to `.dev-workflows/docs-profile.yml` in the TARGET repo — never the plugin259- NEVER push or auto-merge — output a reviewable PR (branch + commit + drafted PR message) for the user to push260- ALWAYS use `choices` arrays for decision points; recommended default first and labelled "(Recommended)"; last choice always `"Other… (describe)"`261- ALWAYS reference plugin paths with `~/.copilot/installed-plugins/ihudak-copilot-plugins/dev-workflows`262- ALWAYS produce the Phase 6 report as the final output, noting any §2.1/§2 model fallback