[PR #3277] [CLOSED] fix(config): reject an unsupported REA_MCP_OUTPUT_SCHEMA_PROFILE before writes #5694

Closed
opened 2026-10-31 01:08:42 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/3277
Author: @paoValle
Created: 10/14/2026
Status: ❌ Closed

Base: main ← Head: fix/3205-output-schema-profile-validation


📝 Commits (1)

  • 2aaee39 fix(config): reject an unsupported REA_MCP_OUTPUT_SCHEMA_PROFILE before writes

📊 Changes

3 files changed (+22 additions, -4 deletions)

View changed files

📝 src/config/environment.ts (+2 -0)
📝 tests/acceptance/setup/piClientSetup.test.ts (+9 -4)
📝 tests/boundary/filesystem/clientConfigurationEnvironment.test.ts (+11 -0)

📄 Description

Summary

Fixes #3205.

A client registration carrying REA_MCP_OUTPUT_SCHEMA_PROFILE: "bogus" passed
setup and doctor while production MCP initialization rejects the same value:
setup rewrote the launcher and reported ready, and doctor reported the
registration aligned with remediation: null. Registration validation parses
known settings through the shared environment schema, and that schema declared
only the input schema profile.

Problem and expected behavior

Smallest trigger, from the issue — a Pi registration with
REA_MCP_OUTPUT_SCHEMA_PROFILE: "bogus":

node scripts/rea.mjs setup --client pi --skill=false --yes --json
node scripts/rea.mjs doctor --client pi --json

Before, both exited 0 and setup rewrote the registration. docs/installation.md:66-73
already names retained output-schema overrides and requires setup and doctor to
report invalid runtime settings before setup writes files, and
src/config/mcpOutputSchemaProfile.ts already rejects other strings with a
named configuration error. Expected: setup fails with needs_human and
remediation naming REA_MCP_OUTPUT_SCHEMA_PROFILE, the registration bytes are
preserved, doctor reports the registration invalid with the same named
remediation, and the valid values full and off keep working.

Change and scope

src/config/environment.ts declares REA_MCP_OUTPUT_SCHEMA_PROFILE with
mcpOutputSchemaProfileSchema.optional(), the same way the input profile is
declared two lines above. The schema object is the one production MCP
initialization already validates with, so setup/doctor acceptance and server
startup can no longer diverge. No new parser, no new module: the existing
mcpOutputSchemaProfile.ts remains the owner of the accepted values.

Not included: no AppConfig field (mcpInputSchemaProfile is carried there but
read nowhere; createServer reads the raw snapshot environment), no change to
the acceptance policy for either profile, and no change to the MCP server's
selection.

Contract and boundary impact

  • Semantic owner and earliest changed stage: shared environment validation (src/config/environment.ts), reached by registration validation before any write.
  • Contribution scope fit and linked maintainer decision: not applicable — ordinary validation fix inside existing boundaries.
  • CLI and MCP/tool-catalog contract: setup/doctor now fail for an unsupported literal; the MCP server's full/off selection is unchanged.
  • Provider, bridge, target-format, or platform compatibility: none.
  • Evidence, artifact, provenance, or reconstruction contract: none.
  • Target selection, authority, upstream behavior, and cleanup details: none — the failing path stops before any configuration write, and no .rea.backup is created.
  • Generated metadata/package/installation impact: none.

Expected effects: [x] Read existing files or captured data. [x] Change process memory, registers, files, or configuration — setup/doctor only, inside disposable fixture directories; --yes was required for any write. No target interaction.

Evidence and regression coverage

  • Tests added or updated: two invalid rows (empty and bogus) in the existing invalid-environment table of tests/boundary/filesystem/clientConfigurationEnvironment.test.ts, REA_MCP_OUTPUT_SCHEMA_PROFILE: "off" added to the preserved-custom-map case, and the acceptance loop in tests/acceptance/setup/piClientSetup.test.ts now covers both settings with the remediation naming the specific one.
  • Bite check: with src/config/environment.ts reverted and the tests kept, the focused run reports 4 failed | 26 passed — the two new boundary rows (previously already_current) and the two new Pi acceptance cases (previously setup exit 0).
  • Remaining proof gaps: full retention is exercised through createServer rather than a registration write (the enum treats it like the absent default); non-Pi client formats are covered by the boundary table, not by a CLI run per client. Windows not exercised.

Validation performed

  • npm run test:focused -- tests/boundary/filesystem/clientConfigurationEnvironment.test.ts tests/acceptance/setup/piClientSetup.test.ts — Test Files 2 passed (2), Tests 30 passed (30), including the four profile cases.
  • npm run test:local (import-graph selection for the change) — Test Files 31 passed (31), Tests 517 passed (517).
  • npm run check — Tasks: 6 successful, 6 total; formatting, module boundaries (1862 files) and architecture guards (1386 files) clean.
  • End-to-end, bogus: setup --client pi --skill=false --yes --json exits 1 with "status":"needs_human", "state":"invalid" and remediation …has an invalid REA server environment: REA_MCP_OUTPUT_SCHEMA_PROFILE: Invalid option: expected one of "full"|"off". Repair it before rerunning setup.; cmp of the registration before/after reports PRESERVED; doctor --client pi --json exits 1 with "healthy":false and a failing registration:pi check carrying the same named remediation.
  • End-to-end, valid control: after changing only that setting to off, setup exits 0 with "status":"ready", appliedActions:["configured_pi"] and "state":"aligned"; the registration still contains {'REA_MCP_OUTPUT_SCHEMA_PROFILE': 'off'}; doctor --client pi --json exits 0, healthy:true, registration aligned, remediation:null; REA_MCP_OUTPUT_SCHEMA_PROFILE=full mcp doctor --json exits 0 with healthy:true and a server identity.
  • REA_MCP_OUTPUT_SCHEMA_PROFILE=bogus mcp doctor --json — exit 1 with "healthy":false, as before.

Compatibility, safety, and release

  • Breaking changes or migration steps: none for valid configurations. A registration whose output profile is an unsupported literal now fails validation instead of being reported ready; the value is the same one production MCP initialization already refused.
  • Real Hopper/Ghidra, browser, or OS coverage: none needed; no analysis engine is involved.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: none — validation only, no new input source or side effect.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed (docs already describe the setting and full/off).
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

An AI coding agent drafted this change under my direction; I reviewed the diff and ran the
commands above with the output quoted here.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/3277 **Author:** [@paoValle](https://github.com/paoValle) **Created:** 10/14/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix/3205-output-schema-profile-validation` --- ### 📝 Commits (1) - [`2aaee39`](https://github.com/morluto/rea/commit/2aaee39d4ad65936021df16c2429851d10d0d0ff) fix(config): reject an unsupported REA_MCP_OUTPUT_SCHEMA_PROFILE before writes ### 📊 Changes **3 files changed** (+22 additions, -4 deletions) <details> <summary>View changed files</summary> 📝 `src/config/environment.ts` (+2 -0) 📝 `tests/acceptance/setup/piClientSetup.test.ts` (+9 -4) 📝 `tests/boundary/filesystem/clientConfigurationEnvironment.test.ts` (+11 -0) </details> ### 📄 Description ## Summary Fixes #3205. A client registration carrying `REA_MCP_OUTPUT_SCHEMA_PROFILE: "bogus"` passed setup and doctor while production MCP initialization rejects the same value: setup rewrote the launcher and reported `ready`, and doctor reported the registration `aligned` with `remediation: null`. Registration validation parses known settings through the shared environment schema, and that schema declared only the *input* schema profile. ## Problem and expected behavior Smallest trigger, from the issue — a Pi registration with `REA_MCP_OUTPUT_SCHEMA_PROFILE: "bogus"`: ```sh node scripts/rea.mjs setup --client pi --skill=false --yes --json node scripts/rea.mjs doctor --client pi --json ``` Before, both exited 0 and setup rewrote the registration. `docs/installation.md:66-73` already names retained output-schema overrides and requires setup and doctor to report invalid runtime settings before setup writes files, and `src/config/mcpOutputSchemaProfile.ts` already rejects other strings with a named configuration error. Expected: setup fails with `needs_human` and remediation naming `REA_MCP_OUTPUT_SCHEMA_PROFILE`, the registration bytes are preserved, doctor reports the registration invalid with the same named remediation, and the valid values `full` and `off` keep working. ## Change and scope `src/config/environment.ts` declares `REA_MCP_OUTPUT_SCHEMA_PROFILE` with `mcpOutputSchemaProfileSchema.optional()`, the same way the input profile is declared two lines above. The schema object is the one production MCP initialization already validates with, so setup/doctor acceptance and server startup can no longer diverge. No new parser, no new module: the existing `mcpOutputSchemaProfile.ts` remains the owner of the accepted values. Not included: no `AppConfig` field (`mcpInputSchemaProfile` is carried there but read nowhere; `createServer` reads the raw snapshot environment), no change to the acceptance policy for either profile, and no change to the MCP server's selection. ## Contract and boundary impact - Semantic owner and earliest changed stage: shared environment validation (`src/config/environment.ts`), reached by registration validation before any write. - Contribution scope fit and linked maintainer decision: not applicable — ordinary validation fix inside existing boundaries. - CLI and MCP/tool-catalog contract: setup/doctor now fail for an unsupported literal; the MCP server's `full`/`off` selection is unchanged. - Provider, bridge, target-format, or platform compatibility: none. - Evidence, artifact, provenance, or reconstruction contract: none. - Target selection, authority, upstream behavior, and cleanup details: none — the failing path stops before any configuration write, and no `.rea.backup` is created. - Generated metadata/package/installation impact: none. Expected effects: [x] Read existing files or captured data. [x] Change process memory, registers, files, or configuration — setup/doctor only, inside disposable fixture directories; `--yes` was required for any write. No target interaction. ## Evidence and regression coverage - Tests added or updated: two invalid rows (empty and `bogus`) in the existing invalid-environment table of `tests/boundary/filesystem/clientConfigurationEnvironment.test.ts`, `REA_MCP_OUTPUT_SCHEMA_PROFILE: "off"` added to the preserved-custom-map case, and the acceptance loop in `tests/acceptance/setup/piClientSetup.test.ts` now covers both settings with the remediation naming the specific one. - Bite check: with `src/config/environment.ts` reverted and the tests kept, the focused run reports `4 failed | 26 passed` — the two new boundary rows (previously `already_current`) and the two new Pi acceptance cases (previously setup exit 0). - Remaining proof gaps: `full` retention is exercised through `createServer` rather than a registration write (the enum treats it like the absent default); non-Pi client formats are covered by the boundary table, not by a CLI run per client. Windows not exercised. ## Validation performed - `npm run test:focused -- tests/boundary/filesystem/clientConfigurationEnvironment.test.ts tests/acceptance/setup/piClientSetup.test.ts` — `Test Files 2 passed (2)`, `Tests 30 passed (30)`, including the four profile cases. - `npm run test:local` (import-graph selection for the change) — `Test Files 31 passed (31)`, `Tests 517 passed (517)`. - `npm run check` — `Tasks: 6 successful, 6 total`; formatting, module boundaries (1862 files) and architecture guards (1386 files) clean. - End-to-end, `bogus`: `setup --client pi --skill=false --yes --json` exits 1 with `"status":"needs_human"`, `"state":"invalid"` and remediation `…has an invalid REA server environment: REA_MCP_OUTPUT_SCHEMA_PROFILE: Invalid option: expected one of "full"|"off". Repair it before rerunning setup.`; `cmp` of the registration before/after reports `PRESERVED`; `doctor --client pi --json` exits 1 with `"healthy":false` and a failing `registration:pi` check carrying the same named remediation. - End-to-end, valid control: after changing only that setting to `off`, `setup` exits 0 with `"status":"ready"`, `appliedActions:["configured_pi"]` and `"state":"aligned"`; the registration still contains `{'REA_MCP_OUTPUT_SCHEMA_PROFILE': 'off'}`; `doctor --client pi --json` exits 0, `healthy:true`, registration `aligned`, `remediation:null`; `REA_MCP_OUTPUT_SCHEMA_PROFILE=full mcp doctor --json` exits 0 with `healthy:true` and a server identity. - `REA_MCP_OUTPUT_SCHEMA_PROFILE=bogus mcp doctor --json` — exit 1 with `"healthy":false`, as before. ## Compatibility, safety, and release - Breaking changes or migration steps: none for valid configurations. A registration whose output profile is an unsupported literal now fails validation instead of being reported ready; the value is the same one production MCP initialization already refused. - Real Hopper/Ghidra, browser, or OS coverage: none needed; no analysis engine is involved. - Package or release metadata impact: none. - Security, privacy, process, or containment review: none — validation only, no new input source or side effect. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed (docs already describe the setting and `full`/`off`). - [x] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. --- An AI coding agent drafted this change under my direction; I reviewed the diff and ran the commands above with the output quoted here. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 01:08:42 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#5694
No description provided.