Skip to main content

RFC Review: AI Agent Simplified Configuration — SOP Steps, Derivation & Lint

Companion review for simplified-configuration.md, produced by the rfc-reviewer skill. Valid only for the RFC revision in reviewed_rfc_last_updated.

Executive Summary

  • Overall Score: 8.0/10
  • Rating: Strong
  • RFC Type: full-stack · Sub-Type: enhancement (both layers)
  • Assessment Confidence: High
  • Applied Caps/Gates: none (no category < 5.0; deploy order specified; no cross-layer schema mismatch found)
  • Implementation Readiness Verdict: PROCEED with notes — close REV-1 and REV-2 inline before chunks 4–5; neither requires re-architecture
  • Report Path: chatbot/autonomous-ai-agent/rfcs/simplified-configuration-review.md
  • RFC Author: Dimas Fauzi Hidayat (via rfc-starter) | Reviewed: 2026-07-22

An agent can implement most of this RFC without questions: the repo reading guide is evidence-verified to the line, all six ADRs cite real files, the execution plan carries sourced commands, and the rollout matrix has no unaddressed scenario. The biggest strength is the grounding discipline (every anchor was verified this cycle, including the two-producer and refine-shipped discoveries). The biggest gap is the runtime contract seam: the RFC reuses build_routing_rules for step exceptions without saying who flattens nested exceptions into the pack-level rule list (REV-1), and the enum-exit handler cannot disambiguate the target when more than one assign-to-human rule exists, because the wire reason carries no rule identity (REV-2). Both close with one scoping sentence each — that is what stands between "Strong" and "Agentic-Ready".

Quick Verdict

Why this RFC can be implemented agentically:

  • Detail 2.0 Source Verification is fully evidenced per layer (line-level, dated 2026-07-22) — no plausible-but-unverified anchors.
  • Detail 4.D gives 10 ordered chunks with real commands (bundle exec rspec, pnpm test/test:e2e — sourced from Gemfile:60/package.json) and assertable criteria.
  • ADR-3 makes rollback structural (authored keys never deleted), so the rollout plan's flag-OFF recipe is trustworthy.

Why this RFC will cause agent guessing or rework:

  • REV-1: an agent building chunk 2/5 must guess whether FE or BE flattens step exceptions into the routing-rule list.
  • REV-2: an agent building chunk 4 must guess which stored target to apply when user_request_human_handoff arrives and parameters.routing holds several.
  • REV-3: steps[]/exceptions[] request schema is named but not field-pinned (types/required/example payload).

Findings Ledger (carry-forward)

IDSeverityFinding (one line)RFC locationStatusFirst seenResolved inEvidence / fix
REV-1majorException→rule compilation ownership unstated: exceptions live at capabilities[].steps[].exceptions[] but build_routing_rules :520 reads params['routing'] — no section owns the flatteningDetail 1.C (S04 row) · §2.C.1openR1Recommend: SkillPackDerivation flattens step exceptions + agent-level routing into one merged rule list at sync time; FE never mingles exceptions into the routing payload
REV-2majorHandoff target ambiguous with >1 assign-to-human rule: exit.reason carries no rule identity, so EnumExitHandler "read parameters.routing[].target" is a non-deterministic lookup§2.C.3 · Sequence 2 · ADR-4openR1Recommend MVP scoping: one handoff target per agent (new lint check ⑦, mirrors caps pattern); per-rule targets deferred to the Refine-reconciliation phase
REV-3minorsteps[]/exceptions[] request schema not field-pinned (types, required, per-field limits, example JSON) — §2.4 lists key names only§2.4 outbound row 1–2openR1Run generate-api-contract after grooming, or add a Grape params sketch + one example payload
REV-4minor"perf-tagged rspec spec ≤ 500ms p95" — p95 asserted in CI unit specs is flaky; mechanism unspecifiedDetail 4.C row 2 · chunk 2openR1Specify: N=50 runs in a benchmark harness asserting median + p95 with margin, or move the p95 gate to a staging measurement in chunk 10
REV-5minorDry-run CSV handover mechanism ("support workspace") unspecified — transport, location, trigger owner§2.C.4 · Sequence 3openR1Name it: task writes to the existing ops bucket/path + link posted in the support channel; ops runbook line in chunk 8
REV-6minorFE store artifact named loosely ("useAgentStore-equivalent store shape") — actual chatbot-fe store file not pinnedDetail 2.I · chunk 5openR1Pin the real file(s) during chunk 5 (explorer found store/ai-agent/interface.ts; confirm the bot-automation editor's store)

Ledger summary: 6 open (0 blocker / 2 major / 4 minor), 0 fixed this cycle, 0 accepted-risk. REV-1 and REV-2 promoted to the RFC's §5 table.

PRD → RFC Traceability Matrix

PRD ElementRFC SectionCoverage
AISC-S01 (SOP authoring)Detail 1.C row 1 · §2.A · chunk 5–6Full
AISC-S02 (derivation)ADR-1/2 · §2.C.1 · chunk 2Full — REV-1 touches its exception half
AISC-S03 (linter)§2.C.2 · chunk 3Full
AISC-S04 (Pattern A exceptions)§2.A · Detail 1.C row 4 · chunk 5Partial — REV-1 (compilation owner)
AISC-S05 (enum-exit)ADR-4 · §2.C.3 · chunk 4Partial — REV-2 (target disambiguation)
AISC-S06 (editor comprehension)§2.A · chunk 6Full (AC-3 correctly scoped as validation gate, not CI)
AISC-S07 (actions pool)§1 Dependencies · chunk 7Full (degradation path specified)
AISC-S08 (derive-on-save + dry-run)ADR-3 · §2.C.4 · chunks 2, 8Full
AISC-NEG-01..03 (guard rails)chunk 9 · §3 Role×EndpointFull
PRD §6 constraints (flag, perf, caps, 10000)§4.B · ADR-6 · §2.AFull — REV-4 on the perf assertion only
PRD §7 CHG-001..007§2.C modules + §2.A + refine guardFull
PRD §11 observability§3 MonitoringFull

Summary: 10 of 12 PRD threads fully covered, 2 partial (REV-1/REV-2), 0 missing. 0 RFC decisions without a PRD driver (caps + lint severity are RFC-closed items the PRD explicitly delegated).

Scorecard — Full-Stack (18 categories)

#CategorySourceScoreEvidence-Based Rationale
1PRTMerged9.0Forward+reverse matrices, per-story map covers all 8 stories + 3 NEGs, PRD section coverage row-per-section; no contradiction between layers
2TDCMerged8.06 full ADRs with reversibility + coverage checklist; dragged by the two Partial decisions (REV-1 implicit, ADR-4/REV-2)
3CNTFE8.0§2.A pins drawer, exception card, dropdown enum, caps 20/5; REV-6 store naming loose
4SCBFE8.5Detail 2.I explicit create/modify/NOT-touch per layer incl. "skill_pack_builder.rb NOT touched"
5DEPFE8.5Each dependency carries availability status + owner; probe scoped to one option
6NFSFE7.5Perf budget numeric; drag-at-cap note; a11y §3.E present but thin (no contrast/screen-reader spec)
7TPSFE8.0Commands sourced from repo config; cross-layer staging scenario named; REV-4 on p95 mechanism
8DMSBE8.5No-DDL is the decision, documented: jsonb erDiagram, seed SQL, lifecycle n/a reasoned, legacy-key retention stated
9ACVBE7.5Endpoints tagged reused/extended/new-with-justification; 422/403 envelopes defined; REV-3 field-level schema + REV-1 input shape
10DICBE7.5Integrity matrix + byte-identical fixture strong; REV-2 is a consistency hole on the exit path
11FMCMerged8.5FE: lint envelope/degradation/403-race states · BE: push-fail, unknown-reason, stale-target; §2.G confirms FE handles BE's exact codes
12CSSBE8.0Collision map honest (last-write-wins documented as unchanged); dry-run read-only; no new hot path unbudgeted
13SASBE8.5set_role cited; refine 403 server-side (defense in depth); org-scoped target resolution stated
14ROLMerged9.0Deploy order BE-first with reasoning; single-flag decision; 7-row compat matrix incl. rollback rows; non-destructive flag-OFF
15OBSMerged8.55 named events with properties, numeric alert thresholds, owner + cadence; FE analytics rides existing path (lighter)
16SBCBE8.5Producer boundary explicit; DSAI marked observational; second producer explicitly neutralized not extended
17CPAMerged8.5FE: composable/service/Pixel patterns cited to files · BE: AbstractRepository/Dry::Matcher/logger prefix cited · Cross: service-layer casing named
18CDGBEN/ANo compliance trigger: dry-run CSV carries ids only; retention stated in PRD §6

Mermaid validity: 10/10 blocks parse (mmdc, this cycle — recorded in RFC §6 Comment log).

Resource & Cost Advisory

No advisory note beyond RFC §4.F — in-request CPU within budget, bounded one-off batch. Non-blocking.

Decision Closure Assessment

Decision Index

#DecisionStatusCritical Gaps
1ADR-1 derive-at-sync, unpersistedResolved
2ADR-2 chain gates from step orderResolved
3ADR-3 non-destructive derive-on-saveResolved
4ADR-4 enum-exit handler + parameters.routing targetPartialREV-2: target lookup non-deterministic with >1 assign rule
5ADR-5 refine 403 guardResolved
6ADR-6 hard-fail lint, budgetedResolved
7(implicit) exception→rule compilation ownershipPartialREV-1: no section owns the flattening

Aggregate: 5 of 7 Resolved, 2 Partial, 0 Dangling.

Decision 4 — Enum-exit handler + target storage (Partial)

What was decided — "user_request_human_handoff → assign to the target stored Rails-side in parameters.routing[].target" (ADR-4, §2.C.3). Alternatives considered — wire extension rejected (standing dependency rule). Sound. Groundingprocess_async_reply.rb:159-161, controller :243/:288, ai_agent.rb:38. Real. Interface specification — target shape pinned ({type: agent|division, id}); the lookup rule is not: which element of parameters.routing[] applies when several carry targets? Failure handling — stale target and unknown reason covered (S05/ERR-1..2); the multi-target case is the uncovered path. Challenge — agent implementability: an agent would guess "first match" or "last match"; either silently misroutes a tenant's escalation. Suggested resolution — MVP: one handoff target per agent, enforced as lint check ⑦ ("multiple assign-to-human targets configured — MVP supports one"); per-rule targets join the Refine-reconciliation phase where a rule-identity mechanism (or probe-verified reason suffixing) can be designed properly. Open question for author — is one target per agent acceptable for design partners? (PRD's AISC-S05/AC-1 example uses exactly one.)

Decision 7 — Exception compilation ownership (Partial)

What was decided — NOT EXPLICITLY STATED — inferred from Detail 1.C S04 row ("compile exceptions → params['routing'] shape consumed by build_routing_rules (reused)") and §2.C.1's silence. Gap — exceptions are nested per-step in parameters.capabilities[]; build_routing_rules :520-526 maps a flat params['routing']. Someone must flatten; the RFC never says who. Suggested resolution — BE-side: SkillPackDerivation emits the merged rule list (compiled step exceptions first, then agent-level routing rules) and build_routing_rules is refactored to accept that collection. FE keeps exceptions nested in steps only — this also preserves §2.G row 1 ("FE stops sending authored keys") cleanly. Open question for author — rule ordering semantics when a step exception and a global catch-all could both match: exception wins? (Recommend: yes, exceptions compile before catch-all — document one line.)

Full-Stack Deep-Dives

Cross-Layer Contract Verification — §2.G covers the three changed surfaces; casing handled at the service layer (CPA cross-check); mismatches found: 0 (REV-3 is under-specification, not mismatch). Checks: casing ✓, nullability ✓ (optional keys), error shape ✓ (422/403 envelopes consumed), pagination n/a, auth unchanged ✓.

Cross-Layer Rollout Compatibility Matrix — present in RFC §4.A, 7 scenarios, none unaddressed; "frontend first" explicitly avoided by deploy order with a fail-closed fallback. Deploy order: Backend first. Incompatible scenarios: 0.

End-to-End Data Flow — Detail 2.H traces save→derive→lint→push→runtime→assign→event in one place. Gap: the exception-compilation hop inside that chain is the REV-1 seam.

UI State Audit (abbrev., CNT ≥ 7) — drawer: loading/empty/error/success defined (§2.C matrix); partial state n/a (no incremental fetch). Exception card: empty/error/success defined; loading n/a. 2/2 surfaces adequate.

API Contract Completeness (abbrev.) — 4 endpoints: auth ✓, status codes ✓, idempotency stated, examples ✗ (REV-3) → 5/6 on the two extended rows.

Async Job Spec (abbrev.)DryRunLintTask: trigger/retry/idempotency/queue ✓; timeout + concurrency limit unstated (minor, read-only job); delivery mechanism REV-5.

Compliance Trigger Check — PII ✗ · payment ✗ · health ✗ · retention ✓ (stated) · auth data ✗ · cross-border ✗ → CDG: N/A.

Vague Word Audit — spec sections clean of "TBD/maybe/X-or-Y"; two soft spots counted as findings instead: "support workspace" (REV-5), "useAgentStore-equivalent" (REV-6). Dangling alternatives: 0.

Strengths

  • Source Verification actually verified (Detail 2.0): every anchor carries line-level evidence dated this cycle — including the discoveries that reshaped scope (refine shipped, second producer, editor already 3-tab).
  • Rollback is structural, not procedural (ADR-3 + §4.E): flag-OFF works because derive-on-save never deletes authored keys, and a byte-identical passthrough fixture guards it in CI.
  • Scope discipline (Detail 2.I): the NOT-touched list names the seductive wrong turn (skill_pack_builder.rb) explicitly.

Biggest Gaps

  • REV-1 — the one hop in the end-to-end flow with no owner; both chunk 2 (BE) and chunk 5 (FE) could plausibly claim it, which is exactly how cross-layer work gets built twice or not at all.
  • REV-2 — ADR-4's lookup is deterministic only in the single-target world the PRD example happens to use; the RFC generalizes to "exceptions on every step" without generalizing the target resolution.
  • REV-3 — an agent writing the Grape params block and the FE types from §2.4 alone would have to invent field types and requiredness.

Priority Actions

  1. §2.C.1 / Detail 1.C (REV-1) — add one paragraph: SkillPackDerivation owns flattening (step exceptions → merged rule list → build_routing_rules); exceptions compile before agent-level catch-all rules; FE payload keeps exceptions nested in steps only.
  2. ADR-4 / §2.C.2 (REV-2) — add lint check ⑦: one assign-to-human target per agent in MVP; note per-rule targets in the Refine-reconciliation follow-up. Update Sequence 2 note.
  3. §2.4 (REV-3) — pin the steps[]/exceptions[] request schema: field, type, required, limits + one example payload (or schedule generate-api-contract immediately after grooming and link it).
  4. Detail 4.C (REV-4) — replace "perf-tagged rspec ≤ 500ms p95" with the actual mechanism (benchmark harness N=50, assert p95 with margin) or move the p95 gate to the staging chunk.

Backend Contract Addendum

EndpointMethod/PathAuthZRequest ContractResponse ContractError ContractIdempotency/VersioningStatus
Save agentPOST/PATCH /v2/ai_agents(/:id)role-gated ✓key names ✓, field types/required missing (REV-3)existing envelope ✓422 lint envelope ✓last-write-wins ✓ / payload-compatible ✓Missing [field-level schema, example payload]
Refine guardPATCH/POST /v2/ai_agents/:id/refinerole + flag ✓unchanged ✓403 envelope ✓unchanged ✓Complete

Database changes: none (no-DDL decision documented with seed SQL + jsonb shape) — Complete.

Implementation Readiness Checklist

Unblocked: traceability ✓ · failure modes + error catalogs ✓ · config contract ✓ · pattern alignment ✓ · rollout + rollback ✓ · observability ✓ · task decomposition ✓ · UI states ✓ · cross-layer contract ✓ · deploy order ✓ · compat matrix ✓ · flag coordination ✓ · E2E flow ✓ · security/tenancy ✓ · no-DDL documented ✓

Blocked (fix first):

  • REV-1 — compilation ownership sentence (chunks 2/5 boundary)
  • REV-2 — one-target-per-agent scoping + lint check ⑦ (chunk 4)

Verdict: Fix 2 blockers-for-their-chunks first — then ready to implement. (They gate chunks 2/4/5, not chunks 1/3.)

Task Manifest

RFC Detail 4.D specifies 10 ordered chunks with files, commands, and assertable criteria — verified adequate. Amendments from this review: chunk 2 additionally owns the REV-1 flattening + its spec; chunk 3 gains lint check ⑦ (REV-2); chunk 4's probe step unchanged; chunk 8 gains the REV-5 delivery runbook line.

Dangling Decisions Log

None — 0 dangling. The two Partials (REV-1, REV-2) have proposed resolutions above and are promoted to the RFC §5 table.

Open Questions

#QuestionCategorySeverity
1REV-2 scoping: is one assign-to-human target per agent acceptable for MVP/design partners?DIC/TDCBlocking (chunk 4)
2REV-1 ordering: does a step exception always win over a global catch-all rule when both match?ACV/TDCBlocking (chunk 2)
3REV-4: CI benchmark harness vs staging measurement for the 500ms p95 gate?TPSImportant
4REV-5: exact dry-run CSV destination + trigger owner?OBS/opsImportant

Evidence Notes

  • Detail 2.0 Source Verification — line-level, dated; scored PRT/CPA up.
  • §2.C.3 + Sequence 2 — the multi-target read revealed REV-2; scored DIC/TDC down.
  • Detail 1.C S04 row vs §2.C.1 — the compilation-ownership silence (REV-1); scored ACV down.
  • §4.A rollout matrix + ADR-3 — no unaddressed scenario; scored ROL 9.0.
  • §2.4 — key names without types (REV-3); capped ACV at 7.5.
  • Discussion/comment sections excluded from scoring evidence per skill rules (§6 Comment log used only for the mermaid validation record).

Review History

CycleDateReviewed RFC revisionScoreVerdictFindings open → fixedNotes
R12026-07-222026-07-22 / ffce4808.0PROCEED with notes6 open (2 major, 4 minor), 0 fixedFirst review; REV-1/REV-2 promoted to RFC §5; mermaid 10/10
R22026-07-232026-07-23 (delta)8.0PROCEED with notes6 open, 0 fixed, 0 newDelta re-review after ut-2026-07 (Iteration II UT) grounding: RFC gained hierarchy-copy scope (Design References), THEN-visual-weight brief item, §5 row 6 resolved→narrowed + row 6b scope record. Additive evidence only — no finding status change; REV-1..6 unchanged; no new mermaid blocks