Skip to content

feat(#4313): apply connector config defaults at resolve time - #4314

Merged
mareklibra merged 5 commits into
mainfrom
agent/4313-connector-config-defaults
Aug 19, 2026
Merged

feat(#4313): apply connector config defaults at resolve time#4314
mareklibra merged 5 commits into
mainfrom
agent/4313-connector-config-defaults

Conversation

@fullsend-ai-coder

Copy link
Copy Markdown
Contributor

Add optional defaultValue field to ConfigFieldMeta and apply it as a third precedence layer in RuntimeConfigResolver: DB override → YAML baseline → field default → undefined.

Default values per OpenSpec task 1.8:

  • schedule.intervalMs: 300000 (5 min) — jira, github, gitlab
  • batchSize: 100 — jira, github, gitlab
  • timeout.connectionMs: 30000 (30 s) — jira only

Defaults are NOT added via Zod .default() to preserve "unset" semantics: validateConfigValue(key, undefined) still returns undefined, and resolver precedence is respected. Instead, the defaultValue property on ConfigFieldMeta is read by a new getFieldDefault() helper, which the resolver calls when neither DB nor YAML provides a value.

Fields without defaults (enabled, endpoint, schedule.cron) continue to return undefined when absent.

Bumps BOOST_CONFIG_SCHEMA_VERSION from 4 to 5.


Closes #4313

Post-script verification

  • Branch is not main/master (agent/4313-connector-config-defaults)
  • Secret scan passed (gitleaks — e6c850f7dd03d646d614fb0c74f80e7e4b9d0026..HEAD)
  • Pre-commit hooks passed (authoritative run on runner)
  • Tests ran inside sandbox

@fullsend-ai-coder fullsend-ai-coder Bot added the ready-for-review Agent PR ready for human review label Aug 14, 2026
@rhdh-gh-app

rhdh-gh-app Bot commented Aug 14, 2026

Copy link
Copy Markdown

Important

This PR includes changes that affect public-facing API. Please ensure you are adding/updating documentation for new features or behavior.

Changed Packages

Package Name Package Path Changeset Bump Current Version
@red-hat-developer-hub/backstage-plugin-boost-backend workspaces/boost/plugins/boost-backend minor v0.6.0

@codecov

codecov Bot commented Aug 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 61.49%. Comparing base (d12494f) to head (2e59046).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4314   +/-   ##
=======================================
  Coverage   61.49%   61.49%           
=======================================
  Files        2534     2534           
  Lines      101630   101642   +12     
  Branches    28464    28479   +15     
=======================================
+ Hits        62496    62509   +13     
+ Misses      38567    38566    -1     
  Partials      567      567           
Flag Coverage Δ *Carryforward flag
adoption-insights 84.55% <ø> (ø) Carriedforward from 3dfafca
ai-integrations 67.70% <ø> (ø) Carriedforward from 3dfafca
app-defaults 48.37% <ø> (ø) Carriedforward from 3dfafca
augment 46.67% <ø> (ø) Carriedforward from 3dfafca
boost 79.41% <100.00%> (+0.08%) ⬆️
bulk-import 72.79% <ø> (ø) Carriedforward from 3dfafca
cost-management 13.55% <ø> (ø) Carriedforward from 3dfafca
dcm 67.21% <ø> (ø) Carriedforward from 3dfafca
e2e-adoption-insights 60.00% <ø> (ø) Carriedforward from 3dfafca
e2e-extensions 62.13% <ø> (ø) Carriedforward from 3dfafca
e2e-global-header 49.45% <ø> (ø) Carriedforward from 3dfafca
e2e-homepage 43.49% <ø> (ø) Carriedforward from 3dfafca
e2e-intelligent-assistant 46.68% <ø> (ø) Carriedforward from 3dfafca
e2e-orchestrator 49.51% <ø> (ø) Carriedforward from 3dfafca
e2e-quickstart 55.21% <ø> (ø) Carriedforward from 3dfafca
e2e-scorecard 50.21% <ø> (ø) Carriedforward from 3dfafca
e2e-theme 16.36% <ø> (ø) Carriedforward from 3dfafca
extensions 56.59% <ø> (ø) Carriedforward from 3dfafca
global-floating-action-button 71.18% <ø> (ø) Carriedforward from 3dfafca
global-header 66.50% <ø> (ø) Carriedforward from 3dfafca
homepage 47.50% <ø> (ø) Carriedforward from 3dfafca
install-dynamic-plugins 59.95% <ø> (ø) Carriedforward from 3dfafca
intelligent-assistant 75.42% <ø> (ø) Carriedforward from 3dfafca
konflux 91.98% <ø> (ø) Carriedforward from 3dfafca
lightspeed 69.02% <ø> (ø) Carriedforward from 3dfafca
mcp-integrations 83.40% <ø> (ø) Carriedforward from 3dfafca
orchestrator 70.92% <ø> (ø) Carriedforward from 3dfafca
quickstart 63.74% <ø> (ø) Carriedforward from 3dfafca
sandbox 79.56% <ø> (ø) Carriedforward from 3dfafca
scorecard 87.36% <ø> (ø) Carriedforward from 3dfafca
theme 88.91% <ø> (ø) Carriedforward from 3dfafca
translations 5.12% <ø> (ø) Carriedforward from 3dfafca
x2a 79.20% <ø> (ø) Carriedforward from 3dfafca

*This pull request uses carry forward flags. Click here to find out more.


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d12494f...2e59046. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mareklibra

Copy link
Copy Markdown
Member

/fs-fix changeset and all known issues so far (like CI)

@fullsend-ai-coder

fullsend-ai-coder Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ✅ Success · Started 6:51 AM UTC · Completed 7:10 AM UTC

Commit: e6a4a06 · View workflow run →

fullsend-ai-coder Bot added a commit that referenced this pull request Aug 17, 2026
- Add changeset for connector config defaults feature (minor bump)
- Remove stale changeset from previous release (already consumed on main)
- Regenerate frontend report.api.md to match API Extractor output,
  fixing the CI "check api reports" step failure

Addresses review feedback on #4314
@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🔧 Fix agent — iteration 1 (human-triggered)

Addressed both issues from /fs-fix instruction: (1) added proper changeset for the connector config defaults feature and removed the stale changeset from a previous release, (2) fixed CI by regenerating the frontend API report to match API Extractor output.

Fixed (2):

  1. missing changeset for boost-backend package: Created new changeset connector-config-defaults.md for the defaults feature (minor bump). Removed stale connector-config-schemas.md that was already consumed by Version Packages on main.
  2. CI failure in check api reports and generate API reference step: Regenerated frontend report.api.md (plugins/boost/report.api.md) to match API Extractor output. The committed version had incorrect property ordering that did not match what backstage-repo-tools api-reports generates with tsc:full compilation.

Tests: passed

Updated by fullsend fix agent

@mareklibra

Copy link
Copy Markdown
Member

/fs-review

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 17, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 7:32 AM UTC · Completed 7:49 AM UTC

Commit: e079b54 · View workflow run →

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 17, 2026

Copy link
Copy Markdown

Review

Reason: stale-head

The review agent reviewed commit 3dfafcaeddf99b5db907097f29e6f6bf2b5a1d96 but the PR HEAD is now 2e5904682a519bdfc476a86efeae81fcc8af672b. This review was discarded to avoid approving unreviewed code.

Previous run

Review

Findings

Medium

  • [behavioral-contract-change] workspaces/boost/plugins/boost-backend/src/config/RuntimeConfigResolver.ts:96resolve() now returns a field default value (e.g. 300000, 100, 30000) instead of undefined when neither DB override nor YAML baseline is set. This changes the observable contract of a public method. Consumers checking for undefined to distinguish "not configured" from "has a value" will see different behavior. The method's return type did not change (Promise<unknown | undefined>), so consumers have no compile-time signal.
    Remediation: Verify no external consumer relies on undefined to distinguish "not configured." Consider offering a separate method or source indicator (see issue Connector Config Admin UI (issue 28 of 29) #4066).

  • [stale-description] workspaces/boost/openspec/changes/connector-config-hot-reload/specs/config-schemas/spec.md:5 — Spec header describes RuntimeConfigResolver as using "two-layer resolution (YAML baseline + DB overrides)." The PR changes this to a three-layer model (DB override → YAML baseline → field default).
    Remediation: Update to "three-layer resolution."

  • [stale-description] workspaces/boost/openspec/changes/connector-config-hot-reload/design.md:7 — Multiple references to "two-layer config model" (lines 7, 45) are now stale after field-default layer addition.
    Remediation: Update to "three-layer config model."

  • [stale-description] workspaces/boost/openspec/changes/connector-config-hot-reload/proposal.md:9 — Lines 9, 20, 41 describe RuntimeConfigResolver as "two-layer config model" and "two-layer resolution." Stale after field-default layer addition.
    Remediation: Update "two-layer" references.

Low

  • [JSDoc consistency] workspaces/boost/plugins/boost-backend/src/config/RuntimeConfigResolver.ts:61 — The class-level JSDoc still says "Two-layer configuration resolver" but the PR adds a third precedence layer. Method-level JSDoc was correctly updated.

  • [resolve() vs resolveAll() consistency] workspaces/boost/plugins/boost-backend/src/config/RuntimeConfigResolver.ts:46resolve() uses value !== undefined to decide fallback while resolveAll() uses effective.has(key). These differ semantically when a Map key exists with value undefined. Cannot happen today but would cause disagreement if a future code path sets a key to undefined.

  • [architectural-coherence] workspaces/boost/plugins/boost-backend/src/config/RuntimeConfigResolver.ts:95resolve() applies defaults per-call via getFieldDefault() while resolveAll() iterates all keys to layer defaults. The asymmetry is functionally correct but worth noting for future maintainers.

  • [behavioral-contract-change] workspaces/boost/plugins/boost-backend/src/config/RuntimeConfigResolver.ts:118resolveAll() now includes entries for keys with field defaults even when not set in DB or YAML. Consumers using map.has(key) to check explicit configuration will see a behavioral difference.

  • [version-constant-change] workspaces/boost/plugins/boost-backend/src/config/schemas.ts:190BOOST_CONFIG_SCHEMA_VERSION bumped from 4 to 5. Cross-repo consumers or migration scripts asserting version == 4 will need updating.

  • [Accessor function pattern consistency] workspaces/boost/plugins/boost-backend/src/config/schemas.ts:558getFieldDefault() casts boostConfigFields[key] as ConfigFieldMeta without | undefined, whereas isSensitiveField() uses ConfigFieldMeta | undefined with optional chaining.

  • [JSDoc punctuation consistency] workspaces/boost/plugins/boost-backend/src/config/schemas.ts:170 — The defaultValue field JSDoc is a run-on sentence. Existing field JSDoc in the same interface uses short single-sentence descriptions.

  • [stale-description] workspaces/boost/specifications/prd/platform-operations-deployment.md:168 — Describes configuration engine as "Two-layer resolution." Now incomplete after field-default layer addition.

  • [missing-documentation] workspaces/boost/AGENTS.md:84 — Config registration checklist does not mention the new optional defaultValue property on ConfigFieldMeta.

  • [stale-description] workspaces/boost/openspec/changes/connector-config-hot-reload/tasks.md:20 — Tasks 2.3 and 2.9 reference "two-layer merge." Now three-layer.

Previous run (2)

Review

Findings

Medium

  • [stale-doc] workspaces/boost/AGENTS.md:83 — The "Adding new config fields" checklist instructs contributors to register fields with "a Zod schema, configScope, and description" but does not mention the new optional defaultValue property on ConfigFieldMeta. Contributors adding fields with defaults may not discover this property from the checklist alone.
    Remediation: Update step 2 to mention defaultValue as an optional property.

Low

  • [edge-case] workspaces/boost/plugins/boost-backend/src/config/RuntimeConfigResolver.tsresolve() guards the field-default fallback with value !== undefined, while resolveAll() uses !effective.has(key). These differ if a key is present in the map with an explicit undefined value. Currently unreachable (the map never stores undefined), but the inconsistent idiom is worth harmonizing.

  • [stale-doc] Several openspec documents describe RuntimeConfigResolver as a "two-layer" model (DB override + YAML baseline). With the addition of field defaults, this is now a three-layer model:

    • openspec/changes/platform-operations-deployment/specs/runtime-config/spec.md
    • openspec/changes/connector-config-hot-reload/specs/config-schemas/spec.md
    • openspec/changes/connector-config-hot-reload/design.md
    • openspec/changes/connector-config-hot-reload/proposal.md
  • [incomplete-doc] workspaces/boost/openspec/changes/connector-config-hot-reload/specs/config-schemas/spec.md:95 — The "Default Values" requirement says "schema provides default value" without clarifying the mechanism. Now that defaults use ConfigFieldMeta.defaultValue (not Zod .default()), clarifying this would prevent future misunderstanding.

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review fullsend-ai-review Bot added the requires-manual-review Review requires human judgment label Aug 17, 2026
@mareklibra

Copy link
Copy Markdown
Member

/fs-review

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 17, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 11:27 AM UTC · Completed 11:45 AM UTC

Commit: 3d124d1 · View workflow run →

@fullsend-ai-review fullsend-ai-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the review comment for full details.


Note: The following inline comments could not be posted on the diff (GitHub returned 422) and are included here instead:

  • workspaces/boost/plugins/boost-backend/src/config/RuntimeConfigResolver.ts:96: [medium] behavioral-contract-change

resolve() now returns a field default value instead of undefined when neither DB override nor YAML baseline is set. This changes the observable contract of a public method. Consumers checking for undefined to distinguish 'not configured' from 'has a value' will see different behavior. The method's return type did not change (Promise<unknown | undefined>), so consumers have no compile-time signal.

Suggested fix: Verify no external consumer relies on undefined to distinguish 'not configured.' Consider offering a separate method or source indicator (see issue #4066).

  • workspaces/boost/plugins/boost-backend/src/config/RuntimeConfigResolver.ts (file-level): Line 61 · [low] JSDoc consistency

The class-level JSDoc still says 'Two-layer configuration resolver' but the PR adds a third precedence layer. Method-level JSDoc was correctly updated.

  • workspaces/boost/plugins/boost-backend/src/config/RuntimeConfigResolver.ts (file-level): Line 46 · [low] resolve() vs resolveAll() consistency

resolve() uses value !== undefined to decide fallback while resolveAll() uses effective.has(key). These differ semantically when a Map key exists with value undefined. Cannot happen today but would cause disagreement if a future code path sets a key to undefined.

  • workspaces/boost/plugins/boost-backend/src/config/RuntimeConfigResolver.ts:95: [low] architectural-coherence

resolve() applies defaults per-call via getFieldDefault() while resolveAll() iterates all keys to layer defaults. The asymmetry is functionally correct but worth noting for future maintainers.

  • workspaces/boost/plugins/boost-backend/src/config/RuntimeConfigResolver.ts:118: [low] behavioral-contract-change

resolveAll() now includes entries for keys with field defaults even when not set in DB or YAML. Consumers using map.has(key) to check explicit configuration will see a behavioral difference.

  • workspaces/boost/plugins/boost-backend/src/config/schemas.ts:190: [low] version-constant-change

BOOST_CONFIG_SCHEMA_VERSION bumped from 4 to 5. Cross-repo consumers or migration scripts asserting version == 4 will need updating.

  • workspaces/boost/plugins/boost-backend/src/config/schemas.ts:558: [low] Accessor function pattern consistency

getFieldDefault() casts boostConfigFields[key] as ConfigFieldMeta without | undefined, whereas isSensitiveField() uses ConfigFieldMeta | undefined with optional chaining.

  • workspaces/boost/plugins/boost-backend/src/config/schemas.ts:170: [low] JSDoc punctuation consistency

The defaultValue field JSDoc is a run-on sentence. Existing field JSDoc in the same interface uses short single-sentence descriptions.

@mareklibra

Copy link
Copy Markdown
Member

Response on #4314 (comment) fullsend-ai's review:

Medium — resolve() contract change

This is the intended behavior from #4313, not a regression. Optional numeric fields must resolve to a stable effective value (intervalMs 300000, batchSize 100, timeout.connectionMs 30000) when neither DB nor YAML sets them. The return type stays Promise<unknown | undefined> because fields without defaults (enabled, endpoint, schedule.cron) still return undefined.

There are no production resolve() callers on this branch yet (#4060 will be the first). resolveAll() is used by GET /config/status, which wants the effective view — including defaults is correct there.

Source tagging (“using default” vs “explicitly set”) is out of scope here; resolveAll() JSDoc already points that at #4066.

Medium — OpenSpec “two-layer” → “three-layer”

Please don’t mass-replace that wording. getEffectiveConfig() is still a two-layer cache merge (YAML + DB). Field defaults are a read-time fallback applied after that merge, on a per-call copy, and never written to cache. Tasks 2.3 / 2.9 are still accurate.

The one OpenSpec tweak worth doing (from #4313 item 5) is a one-liner on Default Values: “schema provides default” means ConfigFieldMeta.defaultValue, not Zod .default(). I’ll leave that for a follow-up so this PR stays on the resolver change.

Low

  • Class JSDoc still saying “Two-layer” while resolve() documents the default fallback: fair nit; cache merge is still two-layer. Optional follow-up.
  • !== undefined vs !has(key): true but unreachable — the map never stores undefined.
  • Schema version 4 → 5: required by AGENTS.md when fields change; nothing asserts version == 4.
  • getFieldDefault() @public but not in the package entry / API report: real inconsistency with isSensitiveField et al. Either export it or mark @internal in a follow-up.

None of these should block merge.

@gabemontero

Copy link
Copy Markdown
Contributor

you've now got some conflicts @mareklibra given the merges yesterday; but as I mentioned in slack, per you request yesterday, I hope to provide a review sometime today my time - thanks

@gabemontero gabemontero left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah a overall I like what is here and addressing nuance and devil in the details wrt config precedence @mareklibra

aside from needing to rebase (as of this comment) my only ask is not with the code changes themselves, but that you update https://github.com/redhat-developer/rhdh-plugins/blob/main/workspaces/boost/specifications/JIRA-analysis/rhdhplan1505-1-staged-issues.md and

  • add references to #4313 around the 4 of 29 issue #4042 write up
  • including explaining whatever staging or ordering is required between that and minimally #4042
  • and confirm that what remains in #4042 is what's left after presumably #4223 and #4220 are done , as I see the description has less content than the original description as listed in the markdown file ... I'm fine replacing the original desription listed in the markdown with the new one you have

So yeah, even though this PR is only for #4223 I'd like you new issues added in whichever tier and spot in the existing staging you think then need to go ...maybe use a "4.1 of 29" , "4.2 of 29", "6.1 of 29", etc.

If claude and I parsed it correctly, we are talking about #4220 , #4313 , #4286 , #4285

also, what is up with the older #3734 ..... is that still valid ? and if so, again, where does it fit in the staging plan

thanks

fullsend-ai-coder Bot and others added 3 commits August 19, 2026 10:37
Add optional `defaultValue` field to `ConfigFieldMeta` and apply
it as a third precedence layer in `RuntimeConfigResolver`:
DB override → YAML baseline → field default → undefined.

Default values per OpenSpec task 1.8:
- schedule.intervalMs: 300000 (5 min) — jira, github, gitlab
- batchSize: 100 — jira, github, gitlab
- timeout.connectionMs: 30000 (30 s) — jira only

Defaults are NOT added via Zod `.default()` to preserve "unset"
semantics: `validateConfigValue(key, undefined)` still returns
undefined, and resolver precedence is respected. Instead, the
`defaultValue` property on `ConfigFieldMeta` is read by a new
`getFieldDefault()` helper, which the resolver calls when neither
DB nor YAML provides a value.

Fields without defaults (`enabled`, `endpoint`, `schedule.cron`)
continue to return `undefined` when absent.

Bumps BOOST_CONFIG_SCHEMA_VERSION from 4 to 5.

Closes #4313
- Add changeset for connector config defaults feature (minor bump)
- Remove stale changeset from previous release (already consumed on main)
- Regenerate frontend report.api.md to match API Extractor output,
  fixing the CI "check api reports" step failure

Addresses review feedback on #4314
- Document that RuntimeConfigResolver.resolveAll() returns a fresh
  per-call snapshot Map, safe to mutate/retain without affecting
  subsequent resolver calls or the underlying cache
- Note that resolveAll() cannot distinguish synthesized field defaults
  from real DB/YAML values; flagged for the admin UI work in #4066
- Change getFieldDefault() to a generic signature keyed on
  BoostConfigKey so callers get the field's typed schema output
  instead of `unknown`

Signed-off-by: Marek Libra <marek.libra@gmail.com>
@mareklibra
mareklibra force-pushed the agent/4313-connector-config-defaults branch from 3d124d1 to 4b24250 Compare August 19, 2026 08:43
@mareklibra

Copy link
Copy Markdown
Member

Rebased

Record the live splits Gabe asked for (#4042/#4220, #4313/#4286/#4285),
keep #4042 as the RHIDP-15302 root, and note #4223/#4225 closed without merge.

Signed-off-by: Marek Libra <marek.libra@gmail.com>
@mareklibra

Copy link
Copy Markdown
Member

/fs-review

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 19, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 12:19 PM UTC · Completed 12:38 PM UTC

Commit: 3dfafca · View workflow run →

Document that field defaults are a read-time fallback (not Zod
.default()), align resolve() with resolveAll() on Map.has(), and
drop "this PR" from the 6.1 staging slot.

Signed-off-by: Marek Libra <marek.libra@gmail.com>
@sonarqubecloud

Copy link
Copy Markdown

@mareklibra

mareklibra commented Aug 19, 2026

Copy link
Copy Markdown
Member

@gabemontero PTAL

The JIRA-analysis/rhdhplan1505-1-staged-issues.md is updated.

Working on #3734 , I will send comments/changes there.

#3734 is still valid, lives under 1509 / RHIDP-15440, is the UsageTab slice of Issue 24 tasks 3.1–3.2 and is not a 4.x under #4042. Implemented by #3746.

@fullsend-ai-review

Copy link
Copy Markdown

/fs-review

@gabemontero gabemontero left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome / thanks @mareklibra

at least for me, the 6.1 etc. nomenclature helps me organize / understand the staging impact

@gabemontero

Copy link
Copy Markdown
Contributor

hit the merge button at your discretion

@mareklibra
mareklibra merged commit 5b04ff0 into main Aug 19, 2026
36 checks passed
@fullsend-ai-retro

fullsend-ai-retro Bot commented Aug 19, 2026

Copy link
Copy Markdown

🤖 Finished Retro · ✅ Success · Started 1:47 PM UTC · Completed 2:04 PM UTC

Commit: 2e59046 · View workflow run →

@fullsend-ai-retro

Copy link
Copy Markdown

Retro: PR #4314 — apply connector config defaults at resolve time

Workflow: Issue #4313 (manual /fs-triage + /fs-code) → PR #4314 → manual /fs-fix → 3 review agent runs → human approval → merge.

Timeline

  1. Aug 14 11:42 — Triage agent succeeded on issue Connector Config — Apply optional-field defaults at resolve time (OpenSpec task 1.8) #4313 (connector config defaults).
  2. Aug 14 11:55 — Code agent produced PR feat(#4313): apply connector config defaults at resolve time #4314 (10 files, +635/−78). Good implementation but missing changeset and API report regeneration, causing CI failure.
  3. Aug 17 06:49 — 3 days later, human (mareklibra) noticed CI failure and triggered /fs-fix changeset and all known issues.
  4. Aug 17 07:10 — Fix agent created proper changeset and regenerated API report. CI passed.
  5. Aug 17 07:32–11:45 — Two review agent runs. First discarded (stale-head from fix push). Second produced 12 findings: 4 medium, 8 low.
  6. Aug 17 12:21mareklibra approved, responding point-by-point to review findings.
  7. Aug 18 17:42gabemontero requested changes to staging plan documentation (project management, not code).
  8. Aug 19 13:43gabemontero approved after staging docs were updated.
  9. Aug 19 13:46 — PR merged.

Review Agent Assessment

Of 12 findings in the substantive review: 5 were acknowledged true positives (accessor pattern inconsistency, JSDoc nits, code consistency observations), 4 were true observations but zero-risk (intentional behavioral changes per issue requirements), and 3 were false positives where the agent recommended mass-replacing "two-layer" with "three-layer" in documentation. The human correctly explained the cache merge IS two-layer — field defaults are a read-time fallback, not a third cache layer. The agent's recommendation would have introduced architecturally incorrect terminology.

All inline review comments failed with 422 errors and were posted as body text instead.

Human vs. Agent Review Gap

The review agent focused exclusively on code-level findings (behavioral contracts, documentation consistency, code style). The human reviewer (gabemontero) caught an entirely different dimension: project management staging plan documentation needed updating to reflect inter-issue dependencies. This is expected — the review agent's scope is code quality, not project coordination.

Autonomy Readiness

For this class of change (schema/config additions in the boost workspace), the review agent provides informational value but is not ready for autonomous approval. The 25% false positive rate on documentation consistency findings (3 of 12) is too high — the "three-layer" recommendation would have been actively harmful if auto-applied. The agent's true positives were all non-blocking observations that didn't require changes before merge.

Evidence for Existing Issues (no new proposals needed)

  • rhdh-plugins#3745 — The boost workspace AGENTS.md has zero changeset guidance while other workspaces (cost-management, x2a) have explicit instructions. The rhdh-workspace skill defers to workspace AGENTS.md for changeset specifics, creating a broken chain for boost. This directly caused the code agent to skip changeset creation, requiring a 3-day-delayed manual /fs-fix.
  • rhdh-plugins#3757 — API report regeneration instructions exist in boost AGENTS.md but were not followed by the code agent. The recently closed #4311 reconciled contradictory API report commands in boost AGENTS.md on Aug 14 — the same day the code agent ran, suggesting the agent may have used pre-fix instructions.
  • agents#760, fullsend#6039 — All inline review comments failed with 422. This continues to be a persistent issue across PRs.
  • fullsend#1331, fullsend#2399 — First review was discarded due to stale-head race (fix agent pushed between review trigger and completion).
  • agents#420 — The "two-layer" to "three-layer" false positive is a specific instance of the review agent making technical assertions without fully verifying the architectural design.
  • fullsend#6348 — Two workflow runs logged invalid harness: base field is set but harness was not loaded with LoadWithBase errors during dispatch.

Overall Assessment

The code agent produced a strong implementation on the first attempt — the architectural design (defaults as read-time fallback, not cache-layer), the test coverage (100% new code), and the schema versioning were all correct. The main rework was mechanical: missing changeset and API report, both attributable to missing workspace-level guidance. The review agent provided some useful observations but no blocking findings. The 5-day merge timeline was driven by human scheduling, not agent deficiencies.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-review Agent PR ready for human review requires-manual-review Review requires human judgment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Connector Config — Apply optional-field defaults at resolve time (OpenSpec task 1.8)

2 participants