> For the complete documentation index, see [llms.txt](https://docs-lunar.earthly.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs-lunar.earthly.dev/configuration/lunar-config/customization.md).

# customization

Customize Lunar's presentation and behavior.

* `lunar-config.yml -> customization`
* Type: `object`
* Optional

The `customization` object controls optional changes to Lunar's presentation and behavior. Every setting under it rewrites text Lunar shows somewhere: a reply in a pull-request or merge-request thread, the checks report posted on that request, the verdict the `lunar` CLI prints in a CI job, or a line on a Grafana dashboard.

## Templates

Four settings take a template rather than a literal string: [`bypass_template`](#bypass_template), [`bypass_revocation_template`](#bypass_revocation_template), [`checks_template`](#checks_template) and [`ok_release_template`](#ok_release_template). Each is the path to a file written in Go's [`text/template`](https://pkg.go.dev/text/template), the templating language in the Go standard library: ordinary text with `{{ ... }}` actions in it, which Lunar executes against the data its own section lists.

The standard actions, `{{if}}`, `{{range}}`, `{{define}}` and the rest, behave as documented, as do the built-in functions. Lunar adds no helpers of its own and exposes no Git platform API objects. It sets `missingkey=error`, so naming a parameter Lunar does not supply is an error and not an empty string.

What follows holds for all four. [`pr_comments`](#pr_comments) and [`bypass_hint`](#bypass_hint) are not templates.

### Where the file lives

The path is relative to the configuration repository root, even when the `customization:` block is in `lunar-config.d/`. Lunar rejects absolute paths, paths that point outside the repository, and symlinks that resolve outside it.

### When Lunar reads it

Lunar reads the file when it pulls the configuration, validates it by rendering it against representative data, and stores the contents with the manifest. Every later render uses that stored copy, so a Hub replica never needs the repository checkout, and neither does the CI runner that prints the `ok_release_template` output.

A missing file, a template that does not parse, a reference to a parameter that does not exist, or output that is empty or too large fails the pull. Lunar creates no new manifest, and the last published one stays active.

### Limits and fallback

Rendered output must be non-empty and no larger than 64 KiB.

Output that gets posted to a Git platform, meaning the two bypass replies and the checks report, must not contain a line beginning with `/`, because GitHub and GitLab read such a line as a command like `/approve` or `/merge`. Lunar checks this at configuration pull and again on the real output before posting. `ok_release_template` prints to a terminal, so the rule does not apply to it.

A template decides wording and nothing else: verdicts, exit codes and whether a gate blocks are all settled before it runs. If a stored template unexpectedly fails at render time, Lunar logs the error and falls back to the built-in text for that one render.

## `bypass_template`

* `lunar-config.yml -> customization.bypass_template`
* Type: `string`
* Optional

The reply Lunar posts once a [`/lunar bypass` comment](/docs/pr-comments.md#lunar-bypass) has granted a bypass. It lands in the thread the command was written in: on GitHub as a new comment on the pull request, on GitLab as a new note in the discussion the command started. These replies are the audit trail for an override, so every attempt gets its own and Lunar never edits an earlier one.

```yaml
customization:
  bypass_template: templates/bypass-acknowledgement.tmpl.md
```

If this field is omitted, Lunar posts its built-in acknowledgement, which is also a reasonable starting point for a custom one:

{% code title="templates/bypass-acknowledgement.tmpl.md" %}

```gotemplate
{{ if .Error -}}
🌙 **Earthly Lunar could not bypass the merge gate** for @{{ .Actor }}.

> {{ .Error }}

*Nothing was overridden and the gate still applies. Comment `/lunar bypass: <reason>` again to retry.*
{{- else -}}
🌙 **Earthly Lunar merge gate bypassed** by @{{ .Actor }} for commit `{{ .SHA }}`.

Reason:
> {{ .Reason }}

*This override covers only the commit above, so pushing a new commit re-arms the gate. Revoke it with `/lunar bypass rm`.*
{{- end }}
```

{% endcode %}

It opens on `.Error` because a command that failed is answered from this same template. See [reporting a command that failed](#reporting-a-command-that-failed).

Templates receive this typed data:

* `.Actor` (`string`): Git platform username or login, without `@`
* `.SHA` (`string`): full pull-request or merge-request head commit SHA
* `.Reason` (`string`): supplied reason, collapsed to one line before rendering
* `.PullRequestNumber` (`int64`): repository-local pull-request or merge-request number
* `.GitPlatform` (`string`): canonical Git platform name, such as `github` or `gitlab`
* `.Host` (`string`): Git platform host
* `.Repository` (`string`): `owner/repository` path
* `.SourceBranch` and `.TargetBranch` (`string`): pull-request or merge-request branches
* `.Components` (`[]string`): all matched Lunar component names
* `.SelfBypass` (`bool`): whether the commenter authored the pull request or merge request
* `.VerifiedRole` (`string`): provider-qualified role recorded in the bypass ledger, such as `gitlab:maintainer` or `github:admin`
* `.Error` (`string`): why the command could not be carried out, empty when it succeeded

### Reporting a command that failed

A `/lunar bypass` command can fail before Lunar acts on it, most often because the Git platform is rate limiting Lunar and will not serve the pull request. The commenter is told so in the thread, from this same template, with `.Error` set and every other parameter holding whatever was known when the command stopped. `.SHA` and `.Components` are empty when it stopped before resolving them.

Branch on `.Error` first, since the rest of the template describes an override that was never made:

```gotemplate
{{ if .Error }}🌙 Lunar could not bypass the gate for @{{ .Actor }}: {{ .Error }}
{{ else }}🌙 Bypassed by @{{ .Actor }} for commit `{{ .SHA }}`.
{{ end }}
```

A template without a branch for it keeps working. Configuration pull accepts it, and Lunar posts its built-in failure reply for that one comment. The confirmation the template was written for is unaffected.

### Extra limits on the bypass replies

Both bypass replies are held to the [shared limits](#limits-and-fallback), plus a few of their own that keep rendering work bounded. `call`, `html`, `js`, `print`, `printf`, `println`, `urlquery` and `with` are unavailable; recursive or overly complex template-call graphs are rejected; and a template may contain one `range`, directly over `.Components`. The file itself must also be no larger than 64 KiB, and the output must not contain `[Earthly Lunar]`, the marker reserved for Lunar's own results comment.

Do not open a template with `.Reason`. The commenter writes it, so a reason spelled `/lunar bypass: ...` would make the reply itself a command. Lunar discards any reply that reads as one and posts its built-in text instead.

## `bypass_revocation_template`

* `lunar-config.yml -> customization.bypass_revocation_template`
* Type: `string`
* Optional

The reply Lunar posts once a [`/lunar bypass rm` comment](/docs/pr-comments.md#lunar-bypass-rm) has withdrawn a bypass. It lands in the same place, and the same way, as the grant reply above.

```yaml
customization:
  bypass_revocation_template: templates/bypass-revocation.tmpl.md
```

Grants and revocations use separate templates, so customizing the grant reply leaves the revocation reply on its built-in text.

The built-in revocation reply, which branches on `.Error` for the same reason:

{% code title="templates/bypass-revocation.tmpl.md" %}

```gotemplate
{{ if .Error -}}
🌙 **Earthly Lunar could not revoke the merge gate bypass** for @{{ .Actor }}.

> {{ .Error }}

*Nothing was withdrawn and any existing override still stands. Comment `/lunar bypass rm` again to retry.*
{{- else -}}
🌙 **Earthly Lunar merge gate bypass revoked** by @{{ .Actor }} for commit `{{ .SHA }}`.
{{ if .Reason }}
Reason:
> {{ .Reason }}
{{ end }}
*The gate is armed again for this commit and reports pending while Lunar re-evaluates it. Comment `/lunar bypass: <reason>` to override it again.*
{{- end }}
```

{% endcode %}

Revocation templates receive the same typed data as `bypass_template`, and are held to the same [extra limits](#extra-limits-on-the-bypass-replies). Two parameters read differently here: `.Reason` is the reason given on the `rm` comment, which is optional and empty when none was given, and `.Components` lists only the components whose bypasses were actually withdrawn. A `/lunar bypass rm` that fails is [reported through this template](#reporting-a-command-that-failed) rather than the grant one. If this field is omitted, Lunar posts its built-in revocation reply.

## `pr_comments`

* `lunar-config.yml -> customization.pr_comments`
* Type: `object`
* Optional

The `pr_comments` object controls when Lunar posts its results comment: a comment on a GitHub pull request, or a note on a GitLab merge request, carrying the body [`checks_template`](#checks_template) renders. Only that comment is affected. Commit statuses, GitHub check runs, the merge gate and the Grafana dashboards all keep reporting on every run.

```yaml
customization:
  pr_comments:
    mode: only_failures
```

### `mode`

* `lunar-config.yml -> customization.pr_comments.mode`
* Type: `string`
* Optional
* Default: `always`

When the results comment is posted. One of:

* `always`: post the comment and keep it updated on every run, including the live "pending" view while collectors are still reporting. This is the default and the historical behavior.
* `only_failures`: the comment is only posted if there are one or more failing checks. Otherwise the comment is omitted entirely. Pending checks are shown by the check run (GitHub) or commit status (GitLab), not by a comment. Once posted, the comment keeps updating as usual, back to all-green once the failures are fixed.

## `checks_template`

* `lunar-config.yml -> customization.checks_template`
* Type: `string`
* Optional

The full Markdown body of the `Earthly Lunar` checks report, the list of policy checks and their status that Lunar publishes for a commit. One template covers all three places the report goes, and `.Surface` tells it which one it is rendering:

* the output text of the GitHub check run (`github-check`)
* Lunar's comment on a GitHub pull request (`github-pr-comment`)
* Lunar's note on a GitLab merge request (`gitlab-mr-note`)

The Grafana dashboards build their own view of the same results, so this template does not reach them.

```yaml
customization:
  checks_template: templates/checks-report.tmpl.md
```

Without `checks_template`, Lunar uses the standard built-in report.

The template cannot change check names, GitHub conclusions, GitLab states, required-check calculation, bypass decisions, or heartbeat behavior.

### Template data

The template renders once for the entire report and receives these report fields:

* `.GitPlatform`: `github` or `gitlab`
* `.Surface`: `github-check`, `github-pr-comment`, or `gitlab-mr-note`
* `.Host`: Git platform host
* `.Repository`: owner and repository path
* `.SHA`: commit being reported
* `.PullRequestNumber`: pull request or merge request number from the first component scope, or `0` for a default-branch check
* `.Components`: all matched component/PR scopes, sorted by full component name and then PR number
* `.Compact`: `true` when a report exceeded the output limit and Lunar retries with a compact rendering

Each entry of `.Components` has these fields:

* `.Component`: full Lunar component name
* `.Name`: short component name, matching the UI
* `.Path`: repository-relative path starting with `/`; the repository root is `/`
* `.PullRequestNumber`: PR or MR number for this component scope
* `.MultiplePRs`: whether this component appears in more than one PR scope at the reported SHA
* `.DetailsURL`: component dashboard URL
* `.Sections`: this component's checks grouped by status
* `.Bypassed`: this component's bypassed checks
* `.Pending`, `.Failed`: evaluation state, separate from individual check results
* `.CommitBypassID`: active commit bypass ID, or an empty string
* `.Empty`: no displayed check sections, bypasses, or pending/failed evaluation to report
* `.Summary`: component verdict summary for compact rendering
* `.GitPlatform`: the report's Git platform, available inside component subtemplates

Your template controls the full layout, including the title, component headings, and evaluation notices. The built-in template hides empty component sections in PR comments; custom templates receive those components and choose whether to show them. The check verdict still includes every matched component.

For example, this template uses one title and lists every component, including empty ones:

```gotemplate
## Policy report

{{range .Components}}### {{.Name}}

`{{.Path}}`

{{if .Pending}}Evaluation pending.{{else if .Failed}}Evaluation failed.{{end}}
{{range .Sections}}* {{.Count}} {{.Title}}
{{end}}
[Details]({{.DetailsURL}})

{{end}}
```

Lunar selects the template from the first matched component's published manifest in the order above. The selection stays the same whichever component triggers the post. A custom PR comment also receives an invisible ownership marker so Lunar can update it later.

Existing templates can continue using top-level `.Component`, `.DetailsURL`, `.Sections`, and `.Bypassed` for single-component reports. These fields are unavailable at the report root when multiple components or PR scopes are present. If an existing template accesses them on a monorepo, Lunar logs the error and uses the built-in report for that render. Move these accesses inside `{{range .Components}}` to customize monorepo reports.

The size and output checks apply to the complete rendered report. If the report remains too large with `.Compact` set, posting fails rather than publishing a truncated report that loses components. The built-in compact rendering retains each visible component's verdict and details link.

Each entry of `.Sections` carries `.Status` (`pass`, `fail`, `no-data`, `skipped`, `error`, or `unknown`), `.Title`, `.Summary`, `.Open`, `.HasRequired`, `.Count`, `.Checks`, and `.AdditionalChecks`, the overflow the built-in template folds into a "more..." block.

`.HasRequired` is true when at least one check in the section can block the gate of the surface being rendered: `block-pr` or `block-pr-and-release` on a pull or merge request, `block-release` or `block-pr-and-release` on a default-branch check run. The built-in template keys the `/lunar bypass` line on it, so a failing section holding only `report-pr` checks reports the failures and offers no command. `.Required` is the same test applied to a single check: the built-in template takes the section icon from `.HasRequired` and each check's icon from `.Required`.

Each check in `.Checks` and `.AdditionalChecks` carries `.Name`, `.PolicyName`, `.Description`, `.Enforcement`, `.Required`, `.Status`, `.FailureMessages`, `.MoreAssertions`, `.Error`, and `.FailureText`. Each entry of `.Bypassed` carries `.Name`, `.Actor`, `.Reason`, `.ExpiresAt` (RFC 3339, empty for a commit-bound bypass), `.CommitBound`, `.FailureMessages`, and `.MoreAssertions`.

`.FailureText` is the policy's own [`failureText`](/configuration/lunar-config/policies.md#failuretext), already rendered and already indented two spaces, and it is empty for every policy that does not set one. The built-in template prints it in place of the `.FailureMessages` bullets, which is what makes `failureText` a replacement rather than an addition; a custom template that ignores the field leaves every policy on the default list.

A check's `.Name` is qualified by the policy it came from, such as `container-scan.max-severity`, so two policies contributing a check of the same name render as two distinguishable lines. Lunar appends the check name to the policy name unless the policy name already ends with it, so the rendered name is also one [`lunar policy bypass-pr`](/docs/lunar-cli.md#lunar-policy-bypass-pr) accepts for `--policy`. `.PolicyName` carries the policy on its own.

Every name in the report is built this way, `.Bypassed` included, so one report never spells the same check two ways. A check that failed before it could report a name, such as one whose policy image could not be pulled, is listed under its policy's name; `Execution failure` appears only when the policy is unknown too. Within a section, `.Checks` arrives with the required checks first, and ordered by that rendered name within each group.

The built-in template is:

```gotemplate
## 🌙 [Earthly Lunar](https://docs-lunar.earthly.dev/)

{{$multiple := gt (len .Components) 1 -}}
{{$previous := "" -}}
{{$shown := false -}}
{{range .Components -}}
{{if not (and (eq $.Surface "github-pr-comment") .Empty) -}}
{{$shown = true -}}
{{if and $multiple (ne $previous .Component)}}### Component {{.Name}}

`{{.Path}}`

{{end -}}
{{$previous = .Component -}}
{{if .MultiplePRs}}**PR #{{.PullRequestNumber}}**

{{end -}}
{{if .CommitBypassID}}Required checks bypassed for this commit (bypass `{{.CommitBypassID}}`).

{{else if .Failed}}❗ Policy evaluation failed; results may be incomplete.

{{else if .Pending}}⏱️ Waiting for this component's policy evaluation.

{{else if and .Empty .Component}}No applicable policy checks.

{{end -}}
{{if $.Compact}}{{.Summary}}. Details omitted to fit GitHub's report limit.

[More Details]({{.DetailsURL}})

{{else}}{{template "component" .}}{{end -}}
{{end -}}
{{end -}}
{{if not $shown}}No applicable policy checks.

{{end -}}
{{define "component"}}{{if .Bypassed}}<details open>
<summary><strong>🔓 {{len .Bypassed}} Bypassed</strong></summary>
{{if eq .GitPlatform "github"}}<br>
{{end}}
*These required checks were failing, but an active bypass lets them through. The merge gate treats them as passing until the bypass expires or is revoked.*

{{range .Bypassed}}* 🔓 `{{.Name}}` — bypassed by {{.Actor}} {{if .CommitBound}}while its commit stands{{else}}until {{.ExpiresAt}}{{end}}: {{.Reason}}
{{range .FailureMessages}}  * {{.}}
{{end}}{{if gt .MoreAssertions 0}}  * {{.MoreAssertions}} more assertions weren't shown
{{end}}{{end}}
</details>

{{end}}{{range .Sections}}<details{{if .Open}} open{{end}}>
<summary><strong>{{template "section-icon" .}} {{.Count}} {{.Title}}</strong></summary>
{{if eq $.GitPlatform "github"}}<br>
{{end}}
{{if .Summary}}{{if eq .Status "error"}}*{{.Summary}}*{{else}}{{.Summary}}{{end}}

{{end}}{{if and (eq .Status "fail") .HasRequired}}*To bypass the required checks, comment with `/lunar bypass: <reason>`*

{{end}}{{range .Checks}}* {{template "check-icon" .}} `{{.Name}}`{{if .Description}} - {{.Description}}{{end}}
{{template "check-failures" .}}{{if gt .MoreAssertions 0}}  * {{.MoreAssertions}} more assertions weren't shown
{{end}}{{if .Error}}  * `{{.Error}}`
{{end}}{{end}}{{if .AdditionalChecks}}
<details>
<summary>{{len .AdditionalChecks}} more...</summary>

{{range .AdditionalChecks}}* {{template "check-icon" .}} `{{.Name}}`{{if .Description}} - {{.Description}}{{end}}
{{template "check-failures" .}}{{if gt .MoreAssertions 0}}  * {{.MoreAssertions}} more assertions weren't shown
{{end}}{{if .Error}}  * `{{.Error}}`
{{end}}{{end}}</details>
{{end}}
</details>

{{end}}{{if and .DetailsURL (or .Component .Sections .Bypassed)}}[More Details]({{.DetailsURL}})

{{end -}}
{{end -}}
{{define "check-failures"}}{{if .FailureText}}{{.FailureText}}{{else}}{{range .FailureMessages}}  * {{.}}
{{end}}{{end}}{{end -}}
{{define "section-icon"}}{{if eq .Status "fail"}}{{if .HasRequired}}❌{{else}}⚠️{{end}}{{else if eq .Status "no-data"}}⏱️{{else if eq .Status "pass"}}✅{{else if eq .Status "error"}}❗{{else}}⁉️{{end}}{{end -}}
{{define "check-icon"}}{{if eq .Status "fail"}}{{if .Required}}❌{{else}}⚠️{{end}}{{else if eq .Status "no-data"}}⏱️{{else if eq .Status "pass"}}✅{{else if eq .Status "error"}}❗{{else}}⁉️{{end}}{{end -}}
```

Validation renders the template once per surface, so one that produces nothing on, say, a GitHub check run fails the pull instead of leaving that surface blank later.

Before rendering, Lunar collapses every data value to one line, except failure messages and `.FailureText`, which keep their line structure: a message has each line after the first re-emitted as an indented list item, so multi-line findings render as a nested list, and `.FailureText` arrives with every one of its lines indented. Either way a value never opens a line of the report, which is what keeps a check name, assertion, bypass reason, or `failureText` from injecting a GitLab quick action.

## `ok_release_template`

* `lunar-config.yml -> customization.ok_release_template`
* Type: `string`
* Optional

The verdict [`lunar policy ok-release`](/docs/lunar-cli.md#lunar-policy-ok-release) prints when the release gate finishes. This is terminal output, so in practice you read it in the log of the CI job that runs the gate. It never reaches a pull or merge request.

```yaml
customization:
  ok_release_template: templates/ok-release.tmpl.md
```

The template replaces the block the CLI prints once the gate reaches a verdict: the summary line plus the failing and bypassed check lists. It does not change the progress messages printed while polling, and it does not apply to `lunar policy ok-pr`.

{% code title="templates/ok-release.tmpl.md" %}

```gotemplate
{{if .Ok}}Release approved for {{.Component}} at {{.SHA}}.
{{else}}Release blocked for {{.Component}} at {{.SHA}}. See https://wiki.example.com/release-gate before retrying.
{{range .FailingChecks}}- {{.PolicyName}}.{{.Name}} [{{.Status}}] ({{.Enforcement}})
{{range .FailureMessages}}  - {{.}}
{{end}}{{end}}{{end}}{{range .BypassedChecks}}Bypassed: {{.Name}} by {{.Actor}} {{if .CommitBound}}while its commit stands{{else}}until {{.ExpiresAt}}{{end}}: {{.Reason}}
{{end}}
```

{% endcode %}

### Template data

* `.Component` (`string`): full Lunar component name
* `.SHA` (`string`): commit the gate was asked about
* `.Ok` (`bool`): the verdict, `true` when nothing blocks the release
* `.FailingChecks`: checks blocking the release, each with `.Name`, `.PolicyName`, `.Status` (`fail` or `no-data`), `.Enforcement`, and `.FailureMessages`
* `.BypassedChecks`: failing checks an active bypass lets through, each with `.Name`, `.PolicyName`, `.Enforcement`, `.Actor`, `.Reason`, `.FailureMessages`, `.ExpiresAt` (RFC 3339, empty for a commit-bound bypass), and `.CommitBound`

Before rendering, Lunar collapses every data value to one line.

Validation renders the template against each verdict the gate can reach: a pass, a pass with bypassed checks, and a block. All three must produce output, so a template that covers a clean pass and a block but not a release that a bypass let through fails the pull instead of printing nothing on that run.

The rendered output is plain text the CLI prints verbatim, so the built-in colors and emoji are replaced by whatever the template produces. The verdict and the exit code always come from the policy evaluation, never from the template.

## `bypass_hint`

* `lunar-config.yml -> customization.bypass_hint`
* Type: `object`
* Optional

A line telling someone stuck behind a gate how to get past it: which channel to ask in, which runbook to follow, or which command to run.

It shows in the Grafana dashboards, directly under the gate banner in the page header. A blocked gate puts "2 checks are required to merge" or "1 check is required to release" in that banner, and the hint goes on the line below. Once every required check passes, or an active bypass clears them, the hint disappears.

The dashboards are the only place it reaches. The pull request comment, the GitHub check run, and the GitLab merge request note carry a built-in hint of their own pointing at [`/lunar bypass`](/docs/pr-comments.md#lunar-bypass); `bypass_hint` does not configure that one, and the only way to change it is to replace the whole [`checks_template`](#checks_template).

A hint appears only where a failing check can block the gate on the page: `block-pr` or `block-pr-and-release` on the PR details dashboard, `block-release` or `block-pr-and-release` on the component dashboard. Checks at `report-pr`, the default [enforcement](/configuration/lunar-config/policies.md#enforcement), or at `score` or `draft`, raise no banner and so produce no hint, on either dashboard and however the hint is set.

```yaml
customization:
  bypass_hint:
    pr: 'Ask in `#eng-guardrails`, or see the [bypass runbook](https://example.com/runbook).'
    release: 'Release blocks need a sign-off in `#eng-guardrails` before bypassing.'
```

* `pr` (`string`): shown on the **PR details** dashboard, under the merge-gate banner.
* `release` (`string`): shown on the **Component details** dashboard, under the release-gate banner.

Each message is a single paragraph of inline Markdown (code spans, links, bold) of at most 4 KiB. Lunar converts it to HTML when it pulls the configuration, so a message that is oversized, not a single paragraph, or made only of whitespace fails the pull. The messages are static: unlike the templates above, they cannot reference the component, commit, or request being viewed.

If a field is omitted or set to the empty string, the dashboards fall back to a built-in hint that quotes the exact bypass command for the gate, including the component and request number: [`/lunar bypass`](/docs/pr-comments.md#lunar-bypass) or `lunar policy bypass-pr` for the merge gate, and `lunar policy bypass-release` for the release gate.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs-lunar.earthly.dev/configuration/lunar-config/customization.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
