docs: DOC-07 CONFIGURATION_REFERENCE appsettings schema (#874)#887
docs: DOC-07 CONFIGURATION_REFERENCE appsettings schema (#874)#887Chris0Jeky merged 6 commits intomainfrom
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 910a8d2c27
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| Complete reference for Taskdeck backend configuration (`appsettings.json`, | ||
| environment variables, and Docker Compose variables). Every key documented | ||
| here maps to a real code path in `backend/src/` — if you see a setting here |
There was a problem hiding this comment.
Document McpServer:DefaultUserId in config reference
The doc claims this is a complete backend configuration reference, but it omits McpServer:DefaultUserId, which is actively read in backend/src/Taskdeck.Infrastructure/Mcp/StdioUserContextProvider.cs. In MCP stdio mode, this key controls which user identity is used; without documenting it, operators can unknowingly run tools against the fallback “first user in DB,” which risks applying actions to the wrong account in multi-user databases.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Code Review
This pull request introduces a comprehensive configuration reference document (docs/platform/CONFIGURATION_REFERENCE.md) that details all backend settings, including JWT authentication, LLM providers, worker configurations, and rate limiting. It also updates CLAUDE.md, deploy/.env.example, and the platform README to link to this new resource. Review feedback identified missing C# types in the conventions section and a typo in the default Gemini model version, which should be corrected to ensure accuracy and prevent potential runtime errors.
|
|
||
| ## Conventions | ||
|
|
||
| - **Type** columns use C# types (`string`, `int`, `bool`, `double`, `int[]`). |
There was a problem hiding this comment.
The list of C# types used in the reference is missing long, string[], and object, which are used later in the document (e.g., lines 126, 180, and 194). Updating this list ensures all types used in the tables are defined in the conventions section.
| - **Type** columns use C# types (`string`, `int`, `bool`, `double`, `int[]`). | |
| - **Type** columns use C# types (string, int, long, bool, double, int[], string[], object). |
| | `Llm:OpenAi:TimeoutSeconds` | `int` | `30` | `HttpClient.Timeout` applied to the OpenAI provider. Values `<= 0` fall back to 30. | No | | ||
| | `Llm:Gemini:ApiKey` | `string` | `""` | Gemini API key. Required to use the Gemini provider. Store as a secret. | Only for `Llm:Provider = Gemini` | | ||
| | `Llm:Gemini:BaseUrl` | `string` | `https://generativelanguage.googleapis.com/v1beta` | Gemini API base URL. | No | | ||
| | `Llm:Gemini:Model` | `string` | `gemini-2.5-flash` | Model identifier. | No | |
There was a problem hiding this comment.
The default model gemini-2.5-flash appears to be a typo. Google's current models are gemini-1.5-flash or the recently announced gemini-2.0-flash; version 2.5 does not exist. This typo is also present in the underlying code (LlmProviderSettings.cs) and appsettings.json. Correcting it here and in the code will prevent 404 errors when the Gemini provider is activated.
| | `Llm:Gemini:Model` | `string` | `gemini-2.5-flash` | Model identifier. | No | | |
| | Llm:Gemini:Model | string | gemini-1.5-flash | Model identifier. | No | |
There was a problem hiding this comment.
Pull request overview
Adds a centralized backend configuration reference document to reduce the need for developers/operators to reverse-engineer appsettings.json and settings bindings from source.
Changes:
- Add
docs/platform/CONFIGURATION_REFERENCE.mddocumenting backend configuration keys, defaults, and env var/Docker Compose mappings. - Cross-link the new configuration reference from existing docs (
CLAUDE.md,docs/platform/README.md) anddeploy/.env.example. - Add introductory guidance in
deploy/.env.examplepointing to the full reference.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| docs/platform/README.md | Adds a pointer to the new configuration reference doc. |
| docs/platform/CONFIGURATION_REFERENCE.md | New comprehensive configuration reference for backend settings, env var overrides, and Docker Compose variables. |
| deploy/.env.example | Adds header comments linking to the configuration reference. |
| CLAUDE.md | Adds the configuration reference to “Key Docs”. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| is blank, **JWT authentication is not registered** and all authenticated | ||
| endpoints return 401 (`AuthenticationRegistration.cs`). In packaged | ||
| non-development runs, `FirstRunBootstrapper.EnsureJwtSecret` generates a | ||
| random 32-byte base64 secret into `appsettings.local.json` when the key is | ||
| missing or equal to the development placeholder. |
There was a problem hiding this comment.
The note here says that when Jwt settings are missing/invalid, JWT auth is not registered and authenticated endpoints will return 401. In the current startup pipeline, app.UseAuthentication() is always enabled (see PipelineConfiguration.ConfigureTaskdeckPipeline), so if AddTaskdeckAuthentication short-circuits, the app will fail to start due to missing authentication services rather than returning 401. Please update this section to reflect the actual behavior (startup failure / misconfiguration error), or adjust the code so auth services are still registered even when JWT is disabled.
| is blank, **JWT authentication is not registered** and all authenticated | |
| endpoints return 401 (`AuthenticationRegistration.cs`). In packaged | |
| non-development runs, `FirstRunBootstrapper.EnsureJwtSecret` generates a | |
| random 32-byte base64 secret into `appsettings.local.json` when the key is | |
| missing or equal to the development placeholder. | |
| is blank, **JWT authentication is not registered** (`AuthenticationRegistration.cs`). | |
| Because the startup pipeline always enables authentication middleware | |
| (`PipelineConfiguration.cs`), this results in an authentication | |
| misconfiguration/startup failure rather than authenticated endpoints simply | |
| returning 401. In packaged non-development runs, | |
| `FirstRunBootstrapper.EnsureJwtSecret` generates a random 32-byte base64 | |
| secret into `appsettings.local.json` when the key is missing or equal to the | |
| development placeholder. |
| | `Llm:OpenAi:TimeoutSeconds` | `int` | `30` | `HttpClient.Timeout` applied to the OpenAI provider. Values `<= 0` fall back to 30. | No | | ||
| | `Llm:Gemini:ApiKey` | `string` | `""` | Gemini API key. Required to use the Gemini provider. Store as a secret. | Only for `Llm:Provider = Gemini` | | ||
| | `Llm:Gemini:BaseUrl` | `string` | `https://generativelanguage.googleapis.com/v1beta` | Gemini API base URL. | No | | ||
| | `Llm:Gemini:Model` | `string` | `gemini-2.5-flash` | Model identifier. | No | | ||
| | `Llm:Gemini:TimeoutSeconds` | `int` | `30` | `HttpClient.Timeout` applied to the Gemini provider. Values `<= 0` fall back to 30. | No | |
There was a problem hiding this comment.
TimeoutSeconds is documented as falling back to 30 when set to <= 0, but LlmProviderSelectionPolicy treats TimeoutSeconds <= 0 as invalid provider configuration and will fall back to the Mock provider instead. Please update the docs to reflect that TimeoutSeconds must be > 0 to use OpenAI/Gemini (the 30s fallback is only applied when configuring the HttpClient, not as an override that makes an invalid provider usable).
| | `Llm:OpenAi:TimeoutSeconds` | `int` | `30` | `HttpClient.Timeout` applied to the OpenAI provider. Values `<= 0` fall back to 30. | No | | |
| | `Llm:Gemini:ApiKey` | `string` | `""` | Gemini API key. Required to use the Gemini provider. Store as a secret. | Only for `Llm:Provider = Gemini` | | |
| | `Llm:Gemini:BaseUrl` | `string` | `https://generativelanguage.googleapis.com/v1beta` | Gemini API base URL. | No | | |
| | `Llm:Gemini:Model` | `string` | `gemini-2.5-flash` | Model identifier. | No | | |
| | `Llm:Gemini:TimeoutSeconds` | `int` | `30` | `HttpClient.Timeout` applied to the Gemini provider. Values `<= 0` fall back to 30. | No | | |
| | `Llm:OpenAi:TimeoutSeconds` | `int` | `30` | `HttpClient.Timeout` applied to the OpenAI provider. Must be `> 0` for the OpenAI provider configuration to be valid; if `HttpClient.Timeout` is being configured and the value is `<= 0`, `30` is used there, but that fallback does not make an invalid provider configuration usable. | No | | |
| | `Llm:Gemini:ApiKey` | `string` | `""` | Gemini API key. Required to use the Gemini provider. Store as a secret. | Only for `Llm:Provider = Gemini` | | |
| | `Llm:Gemini:BaseUrl` | `string` | `https://generativelanguage.googleapis.com/v1beta` | Gemini API base URL. | No | | |
| | `Llm:Gemini:Model` | `string` | `gemini-2.5-flash` | Model identifier. | No | | |
| | `Llm:Gemini:TimeoutSeconds` | `int` | `30` | `HttpClient.Timeout` applied to the Gemini provider. Must be `> 0` for the Gemini provider configuration to be valid; if `HttpClient.Timeout` is being configured and the value is `<= 0`, `30` is used there, but that fallback does not make an invalid provider configuration usable. | No | |
Adversarial self-reviewRan through the 522-line doc as a reviewer who distrusts documentation accuracy. Spot-checked setting names and defaults against real source, checked env-var format, and verified cross-links resolve. Findings
CI statusAll required checks passing (API Integration, Backend Unit, CodeQL, Container Images, Analyze). Acted on
|
Resolves bot review feedback on docs/platform/CONFIGURATION_REFERENCE.md: - Add `long`, `string[]`, `object` to the C# types list in Conventions so every type used in downstream tables is defined (gemini-code-assist). - Clarify that an invalid JWT configuration causes a startup failure (because `UseAuthentication()` is always wired in the pipeline) rather than returning 401 at request time. Note that `FirstRunBootstrapper` normally keeps the app out of this state in packaged runs (Copilot). - Clarify the `Llm:*:TimeoutSeconds` behaviour: values `<= 0` are rejected by `LlmProviderSelectionPolicy` (falls back to Mock). The `HttpClient` substitutes `30` only as a safety net; it does not make an invalid provider usable (Copilot). - Document `McpServer:DefaultUserId`, consumed by `StdioUserContextProvider` in MCP stdio mode. Missing coverage risked routing MCP actions to the wrong account in multi-user installs (chatgpt-codex-connector). The gemini-code-assist suggestion to change `Gemini:Model` from `gemini-2.5-flash` to `gemini-1.5-flash` is rejected: `gemini-2.5-flash` is a real released Google model and matches the defaults in `LlmProviderSettings.cs` and `appsettings.json`. The documented default is accurate.
Fresh adversarial + bot-triage passRe-reviewed the 522-line doc against actual backend source, and triaged all bot findings. Bot findings — triage
Fresh adversarial pass — findingsSpot-checked 15+ settings against real
Commits
CIAll required checks passing on the branch prior to this push (API Integration, Backend Unit, CodeQL, E2E Smoke, Docs Governance, OpenAPI Guardrail, Container Images, Frontend Unit). The new push only touches a single Markdown file under Open concerns
|
Adds a delivery entry for the 8 PROD-00 PRs merged on 2026-04-16 (#884 SEC-28, #885 DOC-06, #887 DOC-07, #886 PERF-09, #888 PERF-10, #889 OPS-29, #890 FE-15, #891 FE-14) with round-2 adversarial review findings: BREACH JWT-in-body correction (compression level Optimal -> Fastest), IPv6/IPv4 healthcheck fix, null-throw sentinel fix, skipRetry opt-out for baseline tests, setpriv entrypoint for upgrade-safe volume ownership. Also bumps the Last Updated date.
…inks - CLAUDE.md Key Docs gains entries for CONFIGURATION_REFERENCE.md (PR #887), CONTRIBUTING.md (PR #885), and SECURITY.md (PR #884) so the post-merge reality is reflected in the agent onboarding surface. - README.md Contributing section cross-links to CONTRIBUTING.md and adds a Security section pointing at SECURITY.md, guarding against a rebase dropping either link.
Adds a delivery entry for the 8 PROD-00 PRs merged on 2026-04-16 (#884 SEC-28, #885 DOC-06, #887 DOC-07, #886 PERF-09, #888 PERF-10, #889 OPS-29, #890 FE-15, #891 FE-14) with round-2 adversarial review findings: BREACH JWT-in-body correction (compression level Optimal -> Fastest), IPv6/IPv4 healthcheck fix, null-throw sentinel fix, skipRetry opt-out for baseline tests, setpriv entrypoint for upgrade-safe volume ownership. Also bumps the Last Updated date.
…inks - CLAUDE.md Key Docs gains entries for CONFIGURATION_REFERENCE.md (PR #887), CONTRIBUTING.md (PR #885), and SECURITY.md (PR #884) so the post-merge reality is reflected in the agent onboarding surface. - README.md Contributing section cross-links to CONTRIBUTING.md and adds a Security section pointing at SECURITY.md, guarding against a rebase dropping either link.
Summary
Closes #874. Adds
docs/platform/CONFIGURATION_REFERENCE.md, a complete reference for every configuration knob the Taskdeck backend exposes:backend/src/Taskdeck.Api/appsettings.jsondocumented with key, type, default, description, and required flag.backend/src/Taskdeck.Application/Services/*Settings.csmapped to their JSON hierarchies.Section__SubKey, array indices, ASP.NET Core host vars) plus the complete list ofTASKDECK_*compose variables fromdeploy/docker-compose.ymlanddeploy/.env.example.CLAUDE.md(Key Docs),docs/platform/README.md, anddeploy/.env.example.Every setting is grounded in a real code path — each row either maps to a
*Settingsclass constructor default or to an explicitGetSection/GetValuecall in the backend. No invented keys.Test plan
appsettings.json,appsettings.Development.json, or aGetSection("...")/GetValue<...>("...")call inbackend/src/.__convention.ci-required.yml).