Qontak Chat | Chatbot & AI | AI Agent Configuration — Adj: SOP-Based Simplified Configuration
HEADER BLOCK
| Field | Value |
|---|---|
| PM | Dimas Fauzi Hidayat |
| PRD Version | 1.6 |
| Status | READY |
| PRD Type | ADJUSTMENT |
| Epic | BOT-4733 |
| Squad | BOT (Chatbot) |
| RFC Link | RFC — SOP Steps, Derivation & Lint |
| Figma Master | N/A — design lives in qontak-designer branch feat/ai-agents-ut-updates (Steps/SOP capability model) |
| Anchor | Yes — Autonomous AI Agent — ANCHOR |
| Labels | epic:qontak-chat | module:chatbot-ai | feature:ai-agent-simplified-config |
| Last Updated | 2026-07-23 |
Decision provenance: every design decision in this PRD is committed in the grilling decision register D1–D9 (2026-07-22). Code anchors verified against
chatbotBE (sync_to_ai_service.rb,process_async_reply.rb) on 2026-07-22.
Table of Contents
- HEADER BLOCK
- 2. CONDITIONAL BLOCK: ADJUSTMENT CONTEXT
- 3. One-liner + Problem
- 4. Target Users + Persona Context
- 5. Non-Goals
- 6. Constraints
- 7. Feature Changes
- 8. API & Webhook Behavior
- 9. System Flow + User Stories + ACs
- 10. Rollout
- 11. Observability
- 12. Success Metrics
- 13. Launch Plan & Stage Gates
- 14. Dependencies
- 15. Key Decisions + Alternatives Rejected
- 16. Open Questions
- PRD CHANGELOG
2. CONDITIONAL BLOCK: ADJUSTMENT CONTEXT
| Field | Detail |
|---|---|
| Parent Anchor PRD | Autonomous AI Agent — ANCHOR |
| This adjustment covers | The tenant configuration surface of the shipped V2 autonomous agent: (a) the capability authoring model (hand-authored required_slots / milestones / gates / completion → SOP Steps with BE derivation), (b) a save-time linter in SyncToAiService, (c) enum-exit handling in process_async_reply (assign-to-human target application; probe-gated resolve), (d) the capability-drawer rebuild onto the Steps card (the shipped editor is already 3-tab — grounded 2026-07-22, AiAgentEditor.vue:3056-3060), (e) migration behavior for existing V2 agents (derive-on-save), and (f) disabling the shipped Refine rail for flag-ON orgs (CHG-007) pending its Steps-model reconciliation. |
| Parent PRD still owns | The V2 runtime engine itself: RAG pipeline, action executors (ActionExecutorFactory / CredentialResolver), the DSAI skill_pack wire contract (unchanged by design), capability vector stores, the async reply pipeline's non-exit paths, and V1 (tree) agents. |
| Reason for adjustment | Evidence-driven: the ut-2026-06-23 usability study (16 participants) found Milestones = the #1 configuration blocker across every batch and both external clients, with non-technical users unable to self-serve ("no hope" — Rere); the RFC gap analysis (rfc-gap-analysis-2026-07-04.md) confirmed the RFC's own worked examples contain the misconfigurations (circular gates, slot mismatches, dangling targets) that tenants are asked to avoid by hand. Iteration-II UT (ut-2026-07, merged 2026-07-23) validates the direction: "Steps" fixed the Milestone blocker and the merged flow removed "same work three times" (both Strong) — verdict "move toward a limited pilot", pending an external non-technical round. |
| Scope boundary | Producer-side + FE + linter change behind flag ai_agent_simplified_config. Touches sync_to_ai_service.rb (derivation + lint), process_async_reply.rb / send_message_with_resolve (enum-exit handling), and the chatbot-fe bot-automation editor. No skill_pack wire-format change, no RAG schema change, no executor change. |
3. One-liner + Problem
One-liner: Let tenant admins configure a working AI agent by writing their SOP as ordered Steps — while Chatbot BE derives and lints the slots, milestones, gates, and completion they can't reason about.
Problem:
The shipped V2 config surface asks tenants to hand-author wire-model artifacts (required_slots, milestone names + action maps, requires_milestone gates, completion types) that even technical users misconfigure — the ut-2026-06-23 study found Milestones incomprehensible to nearly all 16 participants, and the field's recurring production failure modes (premature action fire, deadlocked gates, dead-end error handling) trace directly to this authoring burden. Full background: Autonomous AI Agent — ANCHOR and the D1–D9 decision register.
4. Target Users + Persona Context
Personas inherited from parent: Autonomous AI Agent — ANCHOR.
Adjustment-specific persona note — the ut-2026-06-23 study segments configuring users into three types whose gap this adjustment closes:
| Persona | Role | Goal | Pain | Workaround |
|---|---|---|---|---|
| Primary — Non-technical tenant admin (CS lead / Sales manager, e.g. external participants Dewa, Billy) | Configures the AI agent for their org | Launch a transactional agent without a specialist | Hits a wall at Capabilities/Milestones ("no hope" without help; self-rated 60% confidence) | Relies on the Qontak activation team for every config change (analytics-2026-05: one champion per account across 109 creators) |
| Secondary — Technical tenant admin (IT / systems role) | Builds complex multi-capability agents | Express nested SOP logic safely | Recovers from Milestone confusion but wastes time reverse-engineering the wire model; routing feels duplicated across three surfaces | Reads DSAI RFC examples — which are themselves misconfigured |
| System — Chatbot BE / DSAI teams | Produce and consume the skill_pack | One documented producer of the wire format | Three teams read a spec nobody runs (RFC drift, gap analysis C1/C4) | Tribal knowledge per team |
5. Non-Goals
- Changing the
skill_packwire format or DSAI runtime validators — the whole point is producer-side derivation behind the existing contract. Any THEN option or completion type with no wire representation is cut, not contracted (D8). - Extending the shipped Refine flow to the Steps model — Refine is now live end-to-end (BE
post '/refine'ai_agents_controller.rb:404, landed 2026-07-10 BOT-4594; FEuseRefineAgent.tscallingPATCH /v2/ai_agents/:id/refine, landed 2026-07-14 — supersedes v1.1's stale "zero consumers" evidence). Its pack builder (use_cases/mappers/skill_pack_builder.rb) operates on the authored-field capability shape, so it cannot serve derived Steps-model agents unchanged. MVP decision: Refine is disabled for flag-ON orgs (CHG-007); reconciling Refine with the Steps model is a follow-up phase (§16 row 7). Flag-OFF orgs keep shipped Refine untouched. (D7, re-based on grounding 2026-07-22.) - Tier-2 advanced overrides (manual gate editing,
milestone_reachedcompletion, per-skillturn_budget) — reserved for a future Advanced panel; MVP ships zero Tier-2 decisions. - Migrating V1 (tree) agents — V1 agents stay read-only exactly as today.
- Building new action types — unblocking the actions pool (AISC-S07) is in scope as a dependency; authoring net-new executors is not.
- A visual flow map — the ordered Steps list is the MVP's visibility answer (D6); a flow map is built only if the validation task test fails on cross-capability invisibility.
6. Constraints
| Field | Value |
|---|---|
| Platform | Same as parent — web only (chatbot-fe bot-automation module) |
| Performance | Derivation + linter run synchronously inside the existing save/sync call; combined overhead ≤ 500ms p95 on a 10-capability agent (no perceptible save regression) |
| Backward compat | skill_pack wire format unchanged. Existing V2 agents keep their authored fields until first human edit under the new editor (derive-on-save, D2); legacy authored required_slots / slot_action_args_map / milestone maps remain honored by the passthrough path while the flag is OFF for the org |
| Feature flag | ai_agent_simplified_config | default: OFF — BE system_preferences rollout-group flag; gates the Steps editor (FE) and the derivation/lint path (BE) per org; derive-on-save fires only when ON |
| Rollout note | Before any org is flagged ON: run the batch lint dry-run across all live V2 agents and hand the would-fail list to support (D2). The DSAI staging probe (D3) must complete before the "Resolve conversation" THEN option ships in the dropdown |
| Plan / tier | Same plans as the parent AI Agent feature — this adjustment introduces no new plan gating |
| Role scope | Authoring inherited from existing bot-automation AI-agent config access; no new roles or permission surface (mirrors the story-level Permission Model) |
| Description/goal limit | 10000 characters, enforced as maxlength on the goal/instructions inputs — net-new enforcement: the shipped editor has no maxlength (AiAgentEditor.vue:2157); 10000 exists today only as a create-wizard cap (CreateAiAgent.vue:139) and a counter-only display (AiAgentIdentityForm.vue:300). Input-capping only — never a save-time failure (D9 intent preserved) |
| Dry-run report lifecycle | The batch dry-run would-fail list is exported once per run to the support workspace; retained until GA + 1 quarter, then deleted with the passthrough-path cleanup ticket (§10.1) |
7. Feature Changes
Change ID: CHG-001 — Capability authoring model: Milestones → SOP Steps
| Field | Detail |
|---|---|
| Change Type | Modified behavior + modified component |
| Page | /bot-automation/ai-agents/{id} (capability drawer) |
| Page Intent | Tenant admin defines what a capability does |
| Before | Capability card exposes authored required_slots, a Milestones table, per-action milestone gates (unlockedAfter), an Action-sequence table, and a Completion-condition card ("Completes When") |
| After | Capability = {title, keywords, goal, instructions, steps[], knowledge, actions}. One merged Instructions & Steps card: instructions textarea + drag-reorderable step cards (name, description, optional multi-select actions). No slots, milestone, gate, or completion field anywhere. Design as built on feat/ai-agents-ut-updates. The card carries explicit prompt-hierarchy helper copy — Instructions = always-on rules for this capability; Steps = the ordered procedure the agent executes (and what Qontak compiles into checkpoints) — because ut-2026-07 found hierarchy overlap (Goals/Guidance/Instructions/Steps, "which wins?") is the new #1 comprehension risk (Strong) and Instructions-vs-Steps redundancy is High severity |
| Element | Before | After |
|---|---|---|
| Milestones table | Authored names + action map | Removed — milestones derived per action (<action>_succeeded) |
| Required parameters block | Authored slot list | Removed — slots derived from completion action args |
| Completion card | "Completes When" picker/free-text | Removed — completion derived = last action of last actioned step (D4) |
| Triggers field | triggers | Renamed keywords |
| Description field | description | Renamed goal |
Change ID: CHG-002 — BE derivation layer in SyncToAiService
| Field | Detail |
|---|---|
| Change Type | Modified behavior (producer-side) |
| Page | N/A — backend |
| Page Intent | — |
| Before | build_skill passes tenant-authored required_slots (:134), slot_action_args_map (:135) through; build_milestone_action_map (:408) re-emits an authored map; a gate is emitted only if FE sends a['milestone'] (:432). FE really does send all these fields today (chatbot-fe useSaveAgent.ts:238-284) |
| After | At sync time BE derives: required_slots = arg names of the derived completion action; slot_action_args_map omitted (identity by construction); milestones = one <action>_succeeded per attached action (steps without actions emit none); requires_milestone = chain gates from SOP step order (each actioned step gated on the previous actioned step's success — D1); completion = {type: action_success, action: <last action of last actioned step>}, omitted for knowledge-only capabilities (D4) |
Change ID: CHG-003 — Save-time linter (6 checks)
| Field | Detail |
|---|---|
| Change Type | New behavior in existing save/sync flow |
| Page | Errors surface in the editor at save |
| Page Intent | Tenant admin saves a capability |
| Before | Any config that serializes syncs to DSAI — including circular gates, dangling switch targets, and completion actions missing from the action list (the RFC's own example bugs) |
| After | Sync fails with an actionable, capability-named error on: ① circular gate ② unreachable-milestone gate ③ dangling routing/exception target ④ completion action not in the skill's action list ⑤ slot/arg incoherence (asserted; free by construction) ⑥ cross-capability exception collision — the same action carrying conflicting compiled action_error rules in two capabilities (D5). No partial skill_pack is ever pushed |
Change ID: CHG-004 — Pattern A home: per-step Exceptions
| Field | Detail |
|---|---|
| Change Type | Modified behavior + modified component |
| Page | Capability drawer, step cards |
| Page Intent | Tenant admin defines error recovery for a step |
| Before | Error-recovery rules live only in the agent-wide Routing tab; the prototype's WHEN exposes only an action picker, so a rule matches any failure of that action — Pattern A ("belum terdaftar" → registration) is inexpressible |
| After | Each step carries WHEN/THEN Exceptions: WHEN = this step's action fails, optionally with message containing ⟨text⟩ and/or status code ⟨code⟩ (new FE inputs); THEN = switch capability / assign to human / resolve (probe-gated). Exceptions compile to the existing pack-level {action_error, body_contains, error_code} rules. The global Routing tab is reserved for user-intent + catch-all rules and never carries action_error (D5) |
Change ID: CHG-005 — Closed THEN dropdowns + enum-exit handling in BE
| Field | Detail |
|---|---|
| Change Type | Modified behavior (FE dropdown + BE runtime) |
| Page | Step exceptions + Routing tab THEN controls |
| Page Intent | Tenant admin picks a rule outcome |
| Before | Prototype offers "Switch action" and "Ask clarification" (no wire representation); process_async_reply (app/api/internal_service/v1/ai_agent/use_cases/process_async_reply.rb) routes only on exit.id tree-edges (:159-161) — no enum reason is ever applied, so "assign to human" has no runtime effect and no home for its target |
| After | THEN = switch capability · assign to human · resolve (resolve ships only if the D3 probe confirms verbatim relay). "Assign to human" stores the picked agent/division in parameters.routing and BE applies it when exit.reason == "user_request_human_handoff" arrives; unrecognized reasons fall back to the fallback intent and log. "Switch action" / "Ask clarification" are cut (D8) |
Change ID: CHG-006 — Existing V2 agents: derive-on-save
| Field | Detail |
|---|---|
| Change Type | Modified migration behavior |
| Page | Capability drawer (first edit of a legacy-authored agent) |
| Page Intent | Tenant admin edits an agent authored under the 6-tab editor |
| Before | N/A — new situation introduced by this adjustment |
| After | Published agents are untouched until next human edit. On first save under the new editor, FE no longer sends authored fields; BE derives + lints, and the editor shows a "checkpoints recalculated" notice. Old capabilities open with instructions preserved and steps empty. Pre-rollout, a batch lint dry-run over all live V2 agents produces the would-fail list for support (D2) |
Change ID: CHG-007 — Refine rail disabled for flag-ON orgs
| Field | Detail |
|---|---|
| Change Type | Modified behavior (feature gating) |
| Page | /bot-automation/ai-agents/{id} (editor side rail) |
| Page Intent | Tenant admin refines agent config with AI assistance |
| Before | Refine is live in production: FE RefinePanel/useRefineAgent.ts → PATCH /v2/ai_agents/:id/refine → BE refine.rb builds packs via use_cases/mappers/skill_pack_builder.rb — a second skill_pack producer that reads the authored-field capability shape |
| After | For ai_agent_simplified_config = ON orgs, the Refine rail is hidden with "coming soon for Steps agents" messaging — its pack builder cannot serve derived agents unchanged. Flag-OFF orgs keep shipped Refine exactly as today. Reconciliation (teach SkillPackBuilder + refine_skill_pack_merger the Steps model, or route refine through the derivation layer) is a follow-up phase (§16 row 7) |
8. API & Webhook Behavior
No public API or webhook contract changes. Two internal contract behaviors change (plain-language; endpoint specifics resolved in the RFC):
| # | Behavior | Entity Affected | Triggered By | Expected Behavior | Failure Behavior |
|---|---|---|---|---|---|
| 1 | Derived skill_pack production | skill_pack pushed to qontak-ai-noncore-mrag | Tenant admin saves agent config (flag ON) | BE derives slots/milestones/map/gates/completion from the SOP, lints (6 checks), then pushes a wire-identical skill_pack; DSAI validators run unchanged on generated values | Any lint failure → sync aborts with a capability-named error surfaced in the editor; no partial skill_pack is pushed |
| 2 | Enum-exit application at runtime | Room assignment / resolution in chatbot BE | DSAI async reply carries exit.reason (from a matched rule) | user_request_human_handoff → room assigned to the agent/division stored in parameters.routing; resolve_conversation (probe-gated, D3) → room resolved via the existing resolve path | Unrecognized exit.reason → fall back to the fallback intent (no crash), log the unmapped reason with agent + rule context |
9. System Flow + User Stories + ACs
9.1. System Flow
Flow: Configure → derive → lint → sync → runtime exit mapping · Type: User Journey + API Sequence
- Tenant admin opens the 3-tab editor (Profile / Capabilities / Routing) and edits a capability: title, keywords, goal, instructions, ordered steps (each step optionally carrying actions and WHEN/THEN exceptions).
- Admin saves. FE sends the SOP-shaped capability (no slots/milestone/gate/completion fields).
SyncToAiServicederives: completion (last action of last actioned step),required_slots(completion action's args), milestones (one per attached action), chain gates (SOP step order).- Linter runs the 6 checks against the derived + authored config.
- If any check fails → sync aborts; the editor shows the capability-named error; nothing reaches DSAI.
- If clean → BE pushes the wire-identical
skill_pack; DSAI validators receive machine-generated values. - At runtime, a customer message triggers the agent; a step's action fails matching an exception (
action_error+body_contains) → DSAI applies the rule. - THEN = switch → conversation continues in the target capability. THEN = assign-to-human → DSAI returns
exit.reason: user_request_human_handoff; BE assigns the room to the stored target. THEN = resolve (probe-gated) → BE resolves the room. - If BE receives an unrecognized exit reason → fallback intent + logged unmapped reason.
📊 System Flow — Simplified Configuration
sequenceDiagram
actor Admin as Tenant admin
participant FE as chatbot-fe editor
participant BE as Chatbot BE (SyncToAiService)
participant DSAI as DSAI runtime
Admin->>FE: Author SOP (steps + exceptions), Save
FE->>BE: Capability (no slots/milestones/completion)
BE->>BE: Derive slots, milestones, gates, completion
BE->>BE: Lint (6 checks)
alt lint fails
BE-->>FE: Capability-named error
FE-->>Admin: Save blocked, fix shown
else lint passes
BE->>DSAI: skill_pack (wire unchanged)
end
Note over DSAI: Runtime — step action fails,<br/>exception rule matches
DSAI-->>BE: async reply with exit.reason
alt reason = user_request_human_handoff
BE->>BE: Assign room to stored target
else reason unrecognized
BE->>BE: Fallback intent + log unmapped reason
end
9.2. User Stories
[AISC-S01] — Configure a capability as an SOP
| User Story | As a tenant admin, I want to define a capability as ordered steps with keywords and a goal, so that I can build a working transactional agent without learning slots, milestones, or gates. |
| Before State | Capability card requires authored required_slots, milestone names + action map, per-action gates, and a Completion condition — the exact fields the ut-2026-06-23 study found incomprehensible. |
| After Delta | Capability = title, keywords, goal, instructions, drag-ordered steps (name, description, optional multi-select actions). No wire-model field is ever shown. |
| Importance | Must Have |
| Mockup / Technical Notes | Design: qontak-designer feat/ai-agents-ut-updates — merged Instructions & Steps card, [id].vueData Fields: • title (string, required) — user input• keywords (string[], optional) — user input (renamed from triggers)• goal (string ≤10000, required) — user input (renamed from description)• instructions (string, optional) — user input• steps[] {id, name, description, actions[], exceptions[]} (ordered) — user inputBefore-After Behavior: Admin previously authored 5 wire-model artifacts per capability; after this story they author only their SOP. |
| Acceptance Criteria | — Happy Path — • AC-1: Given the capability drawer under flag ON, when the admin opens it, then only title, keywords, goal, instructions, steps, knowledge, and actions are authorable — no required_slots, milestone, gate, or completion field is rendered.• AC-2: Given a capability with ≥1 step, when the admin drags a step to a new position and saves, then the persisted step order matches the on-screen order after reload. • AC-3: Given a step, when the admin attaches multiple actions via the multi-select picker, then all attached actions persist on that step. — Error / Unhappy Path — • ERR-1: Given a goal or instructions input at 10000 characters, when the admin keeps typing, then input is capped by a net-new maxlength=10000 (the shipped editor enforces nothing today — AiAgentEditor.vue:2157; 10000 exists only as the create-wizard cap and a counter display) and no save-time error can ever occur from length (D9 intent).— Permission Model — • CAN: roles with existing bot-automation AI-agent config access (inherited) • CANNOT: roles without bot-automation access • Unauthorized: module not visible (existing behavior, unchanged) — UI States — • Loading: drawer skeleton while agent config loads • Empty: new capability opens with instructions empty and zero steps (no auto-seeded blank step) • Error: save-blocking lint errors render inline naming the capability (see AISC-S03) • Success: saved capability renders as a clickable card with goal text + up-to-4 keyword chips + +N overflow |
Dependencies: None
[AISC-S02] — Backend derives slots, milestones, gates, and completion
| User Story | As Chatbot BE, I want to generate the wire-model fields from the SOP at sync time, so that DSAI receives a complete, internally consistent skill_pack without hand-authoring. |
| Before State | build_skill passes authored required_slots/slot_action_args_map through (sync_to_ai_service.rb:134-135); build_milestone_action_map re-emits an authored map (:408); gates emitted only when FE sends a['milestone'] (:432); completion authored via the Completion card. |
| After Delta | All four field families are derived per CHG-002; the wire format is byte-compatible with today's contract. |
| Importance | Must Have |
| Mockup / Technical Notes | Technical Notes: derivation runs inside the existing sync call; skill_pack schema unchanged (Non-Goal 1). Multi-action steps: "last action of the last actioned step" is the completion anchor (D4). Producer scope: SyncToAiService is the only producer in scope — the second producer, use_cases/mappers/skill_pack_builder.rb (refine path), is neutralized by CHG-007 (Refine disabled for flag-ON orgs) and inherits derivation in the follow-up phase.Data Fields: • completion (derived) — {type: action_success, action: <tool_name>} or omitted• required_slots (derived) — completion action's arg names• milestones / milestone_action_map (derived) — <action>_succeeded, 1:1• requires_milestone (derived) — chain gates from SOP step order (D1) |
| Acceptance Criteria | — Happy Path — • AC-1: Given a capability whose last actioned step carries action createorder with args [date, fleet_id, email], when BE builds the skill, then completion == {type: "action_success", action: "createorder…"} and required_slots == ["date","fleet_id","email"].• AC-2: Given steps ordered getfleets → calculateprice → createorder, when BE builds the skill, then milestones == ["getfleets_succeeded","calculateprice_succeeded","createorder_succeeded"], milestone_action_map maps 1:1, and createorder.configs.requires_milestone == "calculateprice_succeeded" (chain gate from step order).• AC-3: Given a step with no actions between two actioned steps, when BE derives gates, then the chain skips it — the later actioned step is gated on the previous actioned step's milestone. • AC-4: Given a knowledge-only capability (zero actions on all steps), when BE builds the skill, then completion and milestones are omitted and the sync still succeeds (probe-verified DSAI tolerance, D3).• AC-5: Given a 10-capability agent, when derivation + lint run at save, then combined overhead is ≤ 500ms p95 (enforces §6 Performance). — Error / Unhappy Path — • ERR-1: Given an action whose args contain a nil/blank type, when BE builds the skill, then the action is skipped per the existing args_with_unresolved_type? guard and derivation anchors to the last actioned step whose args resolve — never crashing the sync.— Negative — • NEG-1: Given any capability, when BE builds the skill, then no tag-emission milestone ( [MILESTONE:…]) and no authored slot_action_args_map appears in the output. |
Dependencies: [AISC-S01]
[AISC-S03] — Save-time linter blocks unbuildable configs
| User Story | As a tenant admin, I want save to fail with a clear, capability-named reason when my config would deadlock or dangle, so that I never publish an agent that silently misbehaves. |
| Before State | Any serializable config syncs to DSAI — the RFC's own worked examples (circular gates, dangling targets) pass through unchecked. |
| After Delta | Six deterministic checks run before push (CHG-003); failures abort the sync with actionable errors in the editor. |
| Importance | Must Have |
| Mockup / Technical Notes | Technical Notes: checks ①–④ correspond to real RFC example bugs (D11, §5.3, D12, D13); check ⑤ is free by construction after AISC-S02 but asserted; check ⑥ is new from D5 (pack-level rules are not skill-scoped). Before-After Behavior: Misconfigurations previously reached production and surfaced as runtime failures; after this story they are blocked at save with the offending capability named. |
| Acceptance Criteria | — Happy Path — • AC-1: Given a valid config, when the admin saves, then all 6 checks pass and the sync proceeds. — Error / Unhappy Path — • ERR-1: Given an action gated on a milestone only its own success fires (possible only via legacy data), when saving, then the sync fails naming the action and the cycle. • ERR-2: Given a gate referencing a milestone no action fires, when saving, then the sync fails naming the gate. • ERR-3: Given an exception or routing THEN targeting a non-existent capability, when saving, then the sync fails naming the dangling target. • ERR-4: Given a derived completion action absent from the skill's action list (legacy-data edge), when saving, then the sync fails. • ERR-5: Given the same action attached in two capabilities with conflicting exceptions, when saving, then the sync fails (or warns, per RFC severity decision) naming both capabilities and the action (check ⑥, D5). • ERR-6: Given any linter failure, when it returns, then no partial or invalid skill_pack is pushed to DSAI. |
Dependencies: [AISC-S02]
[AISC-S04] — Per-step exception with message matcher (Pattern A)
| User Story | As a tenant admin, I want to route "when this step's order creation fails because the customer isn't registered, send them to registration", so that a known tool failure recovers deterministically instead of dead-ending or over-escalating. |
| Before State | The wire supports {action_error, body_contains, error_code} (build_routing_when :528-536, fed by build_routing_rules :520-526) but no FE surface exposes the matcher — a rule can only match any failure of an action, so Pattern A is inexpressible. Error rules live only in the agent-wide Routing tab. |
| After Delta | Each step card carries WHEN/THEN Exceptions with a structured WHEN (this step's action + optional message-contains and status-code matchers); exceptions are the only action_error surface (D5); global Routing is reserved for user-intent + catch-all. |
| Importance | Must Have |
| Mockup / Technical Notes | Design: step exception WHEN/THEN cards on feat/ai-agents-ut-updates — restructure required, not just added inputs: the branch's CapabilityStepException today is {when: free-text string, thenMode: switch_action | switch_capability | other(+free text)} with no assign-to-human mode. Change-request to Wulan: structured WHEN (action + optional matchers), closed THEN (switch capability · assign to human · resolve-probe-gated), drop switch_action/other per D8.Data Fields: • exceptions[].when — {action, body_contains?, error_code?} — user input• exceptions[].then — switch_to_skill | assign_to_human | resolve (closed) — user inputBefore-After Behavior: Error recovery moves from an agent-wide tab (research: "same work three times") to the step it protects, with a matcher that finally makes Pattern A expressible. |
| Acceptance Criteria | — Happy Path — • AC-1: Given a step whose action is createorder, when the admin adds an exception WHEN "fails with message containing 'belum terdaftar'" THEN "Switch to registration" and saves, then the rule compiles to {when: {action_error: "createorder…", body_contains: "belum terdaftar"}, switch_to_skill: "registration"} in the pushed skill_pack.• AC-2: Given an exception with no matcher, when saved, then it matches any failure of that step's action (documented behavior, not an error). • AC-3: Given the global Routing tab, when the admin builds a rule, then no action-failure WHEN is offered there — only user-intent and catch-all conditions (D5). — Error / Unhappy Path — • ERR-1: Given a switch target that doesn't exist, when saving, then AISC-S03/ERR-3 blocks the save naming the target. — Permission Model — • CAN / CANNOT / Unauthorized: inherited from AISC-S01 — UI States — • Empty: step shows "Add exception" affordance only • Error: dangling-target lint error names the exception's step • Success: exception renders as WHEN/THEN card on the step |
Dependencies: [AISC-S01], [AISC-S03]
[AISC-S05] — Enum-exit handling in Backend (assign-to-human + probe-gated resolve)
| User Story | As a tenant admin, I want "assign to the Support division" to actually assign the room at runtime, so that handover reaches the right team — and as Chatbot BE, I want to apply enum exit reasons instead of ignoring them. |
| Before State | process_async_reply (app/api/internal_service/v1/ai_agent/use_cases/process_async_reply.rb) routes only on exit.id tree-edges (:159-161); no enum reason is handled — "assign to human" has no runtime effect, and the RFC exit carries no field for the picked target. Resolve exists only as an agent tool call (references[].action_type == "qontak_chat_room_resolve", :182). |
| After Delta | New enum-exit handler: user_request_human_handoff → assign to the target stored Rails-side in parameters.routing; resolve_conversation (BE-minted, only if the D3 staging probe confirms DSAI relays rule-exit reasons verbatim) → resolve the room. Unrecognized reasons → fallback + log. This is the single largest BE work item. |
| Importance | Must Have |
| Mockup / Technical Notes | Technical Notes: target storage in parameters.routing (D3-confirmed plan, ex-Q3); one handler serves all THEN outcomes. Probe first: author a rule with a non-enum reason on staging; verbatim relay → mint resolve_conversation; enum-enforced → cut Resolve from the dropdown (Constraints §Rollout note).Data Fields: • parameters.routing[].target — {type: agent|division, id} — user input (picker)• exit.reason (runtime) — DSAI async reply |
| Acceptance Criteria | — Happy Path — • AC-1: Given THEN "Assign to human" with division "Support", when saved, then the target persists in parameters.routing and the rule emits {exit: {reason: "user_request_human_handoff"}}.• AC-2: Given DSAI returns exit.reason == "user_request_human_handoff", when BE processes the async reply, then the room is assigned to the stored division/agent target.• AC-3: Given the D3 probe confirmed verbatim relay and THEN "Resolve conversation" fired, when BE receives exit.reason == "resolve_conversation", then the room is resolved via the existing resolve path.• AC-4: Given a room that was auto-assigned or auto-resolved by a rule, when a human reassigns or reopens it through the normal inbox flow, then the standard inbox behavior applies unchanged and the same rule does not re-fire on the same failure within that conversation (rollback = existing inbox operations; no new undo surface). — Error / Unhappy Path — • ERR-1: Given an exit reason BE does not recognise, when processing, then BE falls back to the fallback intent (no crash) and logs the unmapped reason with agent + rule context. • ERR-2: Given a stored target that no longer exists (deleted division), when the exit fires, then BE falls back to the org's default assignment path and logs the stale target. |
Dependencies: [AISC-S04]; DSAI staging probe (Dependencies §14)
[AISC-S06] — Steps editor comprehension (3-tab, task-tested)
| User Story | As a tenant admin, I want a Profile / Capabilities / Routing editor where my SOP steps are the visible logic, so that I understand what the agent will do without a specialist. |
| Before State | The shipped editor is already 3-tab (Profile / Capabilities / Routing — AiAgentEditor.vue:3056-3060, grounded 2026-07-22; v1.1's "6-tab" claim was stale). The gap is inside the capability drawer: authored milestone/slot/completion fields and a free-text instruction under a "What steps should the agent follow?" label — research verdict: "the logic is invisible" (P1), non-technical users cannot self-serve. |
| After Delta | Tab structure unchanged; the capability drawer is rebuilt onto the merged Instructions & Steps card — the ordered Steps list is the visibility answer, no Checkpoints tags, no flow map in MVP (D6). |
| Importance | Should Have |
| Mockup / Technical Notes | Design: feat/ai-agents-ut-updates (merged card as built).Before-After Behavior: Progress-display duty moves from milestone artifacts to the SOP steps the tenant authored themselves; FE scope is the drawer rebuild, not a tab collapse. |
| Acceptance Criteria | — Happy Path — • AC-1: Given the editor under flag ON, when it renders, then the existing 3-tab structure (Profile, Capabilities, Routing) is unchanged (regression guard) and the capability drawer contains the merged Instructions & Steps card. • AC-2: Given a saved capability, when the admin views it, then steps render as ordered, numbered cards with their actions and exceptions inline — and no milestone/checkpoint artifact appears anywhere. — Comprehension (validation gate, D6) — • AC-3: Given the validation session, when a non-technical participant is asked to build a 2-step agent unassisted, then they complete the setup — this is the research's own P1 pass criterion; failure is the evidence that buys a flow map (Non-Goal 6). Status: ut-2026-07 (Iteration II, 6 participants — 5 internal + 1 external technical) validated the Steps direction (Strong) but does NOT satisfy this AC — the external non-technical round remains the gate. • AC-4: Given the merged card with the hierarchy helper copy (CHG-001), when a validation participant is asked whether Instructions or Steps governs a described behavior, then they answer correctly — the ut-2026-07 P1 "predictability" re-test for the prompt-hierarchy overlap finding. |
Dependencies: [AISC-S01]
[AISC-S07] — Actions pool available to step and exception pickers
| User Story | As a tenant admin, I want the step action picker and exception pickers to show my real actions pool, so that transactional and recovery flows aren't limited to 4 hardcoded types. |
| Before State | FE ACTION_LIST hardcodes 4 items (qontak_crm_deal_create, qontak_crm_ticket_create, qontak_crm_ticket_update, api) — duplicated in two files (modules/bot-automation/constants/bot-automation-actions-constants.ts:6, the one the editor consumes, and modules/ai-agent/constants/ai-agent-actions-constants.ts:75); plus ACTION_FALLBACK (common/services/main/v1/bot-automation-actions.ts:99) holding 3 different items, marked "until /v1/actions backend ships". Both copies must be retired together. |
| After Delta | Pickers list the tenant's full configured actions pool; graceful degradation to the shipped set when the pool is unavailable. |
| Importance | Could Have (dependency of the full self-service vision) |
| Mockup / Technical Notes | Data Fields: • actions pool (API response) — tenant's configured actions |
| Acceptance Criteria | — Happy Path — • AC-1: Given the tenant's configured actions, when a step or exception picker opens, then the full pool is listed. — Error / Unhappy Path — • ERR-1: Given the pool is unavailable, when a picker opens, then it degrades to the shipped 4-item set and flags the degradation (no silent empty state). |
Dependencies: [AISC-S01]
[AISC-S08] — Derive-on-save migration for existing V2 agents
| User Story | As Chatbot BE, I want legacy-authored agents re-derived only when a human edits them — with a pre-rollout dry-run of who would fail, so that no running production bot changes behavior without a tenant action and support is never blind-sided (D2). |
| Before State | All live V2 agents carry hand-authored slots/milestones/gates saved under the 6-tab editor; some contain latent misconfigurations that the old editor accepted silently. |
| After Delta | Flag-ON orgs: agents untouched until first edit; first save derives + lints with honest messaging. Pre-rollout: batch lint dry-run over all live V2 agents → would-fail list to support. |
| Importance | Must Have |
| Mockup / Technical Notes | Technical Notes: dry-run reuses the AISC-S03 linter in report-only mode; no skill_pack is pushed by the dry-run.Before-After Behavior: Migration risk moves from "silent behavior change at deploy" to "explicit recalculation at the tenant's own edit, with support pre-briefed." |
| Acceptance Criteria | — Happy Path — • AC-1: Given a legacy-authored agent in a flag-ON org, when no one edits it, then its synced skill_pack remains byte-identical to its pre-flag state.• AC-2: Given a legacy capability opened in the new editor, when the drawer renders, then instructions are preserved and the steps list is empty. • AC-3: Given the first save of a legacy agent under the new editor, when derivation succeeds, then the editor shows a "checkpoints recalculated" notice and the derived pack syncs. • AC-4: Given the pre-rollout batch dry-run, when it completes, then every live V2 agent has a lint verdict and the would-fail list (org, agent, failing check) is exported for support. — Error / Unhappy Path — • ERR-1: Given a legacy agent whose config now fails lint, when the tenant first saves it, then the save is blocked with the capability-named error — and the org was already on the support would-fail list (AC-4). — Migration guard — • NEG-1: Given a flag-OFF org, when any agent is saved, then the legacy passthrough path runs unchanged (no derivation, no lint). • AC-5 (rollback): Given an agent that has been re-derived under flag ON, when the org's flag is flipped OFF, then the agent's authored fields are still intact — derive-on-save never deletes them from parameters (derived values live alongside, not instead) — and the next save/sync runs the passthrough over the preserved authored config. Divergence risk (steps edited under ON, then reverting to stale authored config) is accepted and logged. |
Dependencies: [AISC-S03]; flag ai_agent_simplified_config
Guard Rail stories (from Non-Goals)
| User Story | Importance | Acceptance Criteria |
|---|---|---|
| [AISC-NEG-01] — THEN dropdowns never offer unbuildable options (from Non-Goal 1, D8) | Guard Rail | NEG-1: Given any THEN dropdown (step exception or global routing), when it opens, then "Switch action" and "Ask clarification" are absent; only switch capability, assign to human, and (probe-gated) resolve are offered. |
| [AISC-NEG-02] — Refine rail disabled for flag-ON orgs, untouched for flag-OFF (from Non-Goal 2, D7 re-based; CHG-007) | Guard Rail | NEG-1: Given a flag-ON org, when the editor renders, then the shipped Refine rail is hidden/disabled with "coming soon for Steps agents" messaging and PATCH /v2/ai_agents/:id/refine is rejected for that org's agents.NEG-2: Given a flag-OFF org, when the editor renders, then the shipped Refine rail works exactly as today — this adjustment never degrades live Refine for legacy-model orgs. |
| [AISC-NEG-03] — V1 tree agents untouched (from Non-Goal 4) | Guard Rail | NEG-1: Given a V1 (tree) agent, when viewed under flag ON, then it remains read-only exactly as today — no Steps editor, no derivation, no lint. |
10. Rollout
| Field | Detail |
|---|---|
| Rollout type | Controlled rollout with flag |
| Feature flag | ai_agent_simplified_config | default: OFF (BE system_preferences rollout group; gates FE editor + BE derivation per org) |
| Rollout | Stage 1 → Internal QA orgs — new-agent authoring + legacy-edit derivation exercised · Stage 2 → design-partner orgs (opt-in, support pre-briefed with the dry-run would-fail list) · Stage 3 → GA (default ON for new orgs, existing orgs staged) |
| Backward compat | Yes — flag-OFF orgs run the legacy passthrough unchanged; wire format identical |
| Migration | Derive-on-save only (D2): no batch rewrite of live agents, ever; batch lint dry-run is report-only |
10.1. Migration Transition Window
| Field | Detail |
|---|---|
| Old behavior | Flag-OFF orgs (and un-edited agents in flag-ON orgs) sync authored fields via the passthrough path — bit-identical to today |
| New behavior | First human save under the new editor derives + lints; "checkpoints recalculated" notice shown |
| Coexistence period | Indefinite by design — an agent nobody edits is never re-derived; both paths stay live until the last org is flagged ON and edited |
| End state | Passthrough path retired only after GA + one full quarter with zero flag-OFF orgs; tracked as an engineering cleanup ticket, never a silent removal |
11. Observability
New or Modified Events:
| Event Name | Trigger | Properties | Change from parent |
|---|---|---|---|
ai_agent_config_lint_failed | Any of the 6 lint checks blocks a save | org_id, agent_id, capability, check_id (1–6) | New |
ai_agent_config_derived | Successful derivation on save | org_id, agent_id, capability_count, derived_field_counts, legacy_first_save (bool) | New |
ai_agent_exit_reason_applied | Enum-exit handler applies an outcome | org_id, agent_id, reason, outcome (assigned/resolved/fallback), target_type | New |
ai_agent_exit_reason_unmapped | Unrecognized exit.reason received | org_id, agent_id, reason | New — alert if > 0/day per org |
ai_agent_dryrun_completed | Pre-rollout batch lint dry-run finishes | org_count, agent_count, fail_count by check_id | New (one-off, per run) |
Dashboard owner: BOT squad. Alert: ai_agent_exit_reason_unmapped > 0/day per org → investigate same day (it means a rule emits a reason the handler doesn't know).
Post-launch monitoring cadence: weekly review for the first 4 weeks post-GA; if lint-block rate exceeds 20% of saves org-wide or self-serve config rate drops week-over-week, investigate immediately.
Observability otherwise unchanged from parent: Autonomous AI Agent — ANCHOR.
12. Success Metrics
| Metric | Definition | Baseline | Target |
|---|---|---|---|
| ⭐ Self-serve config rate | % of new AI agents that reach published state without activation-team involvement | Near-zero — one champion per account, activation-led (analytics-2026-05, 109 creators) | ≥ 40% of new agents self-served within 60 days of GA |
| Validation task-test pass (pre-launch gate, D6) | Non-technical participant completes a 2-step agent setup unassisted | 0/4 non-technical in ut-2026-06-23; ut-2026-07 (Iteration II) validated direction Strong but sampled no non-technical externals | ≥ 3 of 4 non-technical participants complete unassisted, in the external round |
| Lint catch rate (quality) | Misconfigs blocked at save (ai_agent_config_lint_failed) vs. config-related runtime incidents | N/A — nothing is blocked today | Runtime incidents from the 5 known misconfig classes → 0 for flag-ON orgs |
| Config-related support tickets (efficiency) | Tickets/escalations tagged AI-agent-config | Pull current tag volume pre-GA | −30% for flag-ON orgs within 90 days |
13. Launch Plan & Stage Gates
| Stage | Audience | Duration | Success Gate | Owner |
|---|---|---|---|---|
| 1 — Internal QA | 2 internal orgs | 1–2 weeks | All 6 lint checks exercised; derive-on-save round-trip verified; zero ai_agent_exit_reason_unmapped | BOT QA |
| 2 — Design partners | 3–5 opt-in orgs (support pre-briefed with dry-run list) | 2–4 weeks | ≥ 1 legacy agent per org edited + re-derived with no behavior regression; D6 task-test criterion met in validation | PM (Dimas) |
| 3 — GA | New orgs default ON; existing orgs staged | — | Stage-2 gates held for 2 consecutive weeks; support ticket volume flat or down | PM + BOT lead |
14. Dependencies
| Dependency | Owning Team | Deliverable Needed | Blocking? |
|---|---|---|---|
Design branch merge — feat/ai-agents-ut-updates (Steps model; drawer UI pending visual verification per its docs.md) | Design (Wulan) | Verified prototype = FE build reference; change-request brief covers the exception-model restructure (structured WHEN = action + matchers; closed THEN incl. assign-to-human; drop switch_action/other free-text per D8) + D7/CHG-007 Refine "coming soon" state | NO — FE can build from the branch as-is; verification is a quality gate |
DSAI staging probe (D3): does the runtime relay rule-exit reasons verbatim, and tolerate omitted completion? | BOT BE (probe executed by us — no DSAI work requested) | Probe result recorded in §16; determines whether "Resolve" ships in the THEN dropdown | YES — for the Resolve option only; NO for everything else |
| RFC as-built reconciliation (ex-Q8) | DSAI + BOT | RFC PMDAT/51153994292 updated to the as-shipped wire contract | NO — coordination item, not a build blocker |
Per the standing dependency rule: no DSAI build dependency exists in this MVP — the probe is observational, and the one probe-gated feature (Resolve) has a defined cut path (D3/D8).
📊 Dependency Graph — Simplified Configuration
graph LR
PRD[AISC MVP] -->|NO — quality gate| DES[Design branch verification]
PRD -->|YES — Resolve option only| PROBE[DSAI staging probe D3]
PRD -->|NO — coordination| RFC[RFC as-built reconciliation]
PROBE -->|verbatim relay| RESOLVE[Resolve ships in THEN]
PROBE -->|enum enforced| CUT[Resolve cut from MVP]
15. Key Decisions + Alternatives Rejected
15a — Decisions Made (full reasoning: D1–D9 register)
| Date | Decision | Rationale |
|---|---|---|
| 2026-07-22 | D1 — Gates derive from SOP step order (chain gates) | The config model has no cross-action data-flow structure to read; step order is tenant-authored and deterministic |
| 2026-07-22 | D4 — Completion derived from last actioned step; no authored completion | Design deleted the Completion card; derivation is the PRD's own philosophy applied consistently; D6 task test checks the bet |
| 2026-07-22 | D5 — Per-step Exceptions = only action_error surface; global Routing = intent + catch-all | Matches the researched user mental model; kills the "same work three times" duplication |
| 2026-07-22 | D2 — Derive-on-save + pre-rollout batch dry-run | No production bot changes behavior without a tenant action; support pre-briefed |
| 2026-07-22 | D3 — Probe-then-mint resolve_conversation; cut on enum enforcement | Zero DSAI work if relay is verbatim; honest cut path if not |
| 2026-07-22 | D7 (re-based by grounding) — Refine excluded from the Steps MVP; disabled for flag-ON orgs (CHG-007) | Original "zero consumers" evidence went stale — Refine shipped end-to-end 2026-07-10/14 while drafting. Its pack builder can't serve derived agents unchanged; disabling for flag-ON orgs keeps the MVP decoupled without touching flag-OFF orgs' live feature |
| 2026-07-22 | Flag ai_agent_simplified_config, BE rollout group, default OFF | Standard chatbot flag pattern; enables org-by-org D2 rollout |
15b — Alternatives Rejected
| Alternative | Why Rejected | Date |
|---|---|---|
| Derive gates via data-flow inference (v1.0 R2 as written) | Unimplementable — args are {name,type,description} with no cross-action links; every action would silently fall to "ungated" | 2026-07-22 |
| Name-matching heuristic for gate derivation | Silently wrong on naming coincidences | 2026-07-22 |
| Re-add a completion dropdown (research asked for dropdown, not removal) | Fights the shipped design direction; derivation covers it; task test validates | 2026-07-22 |
| Pattern A in the global Routing tab (v1.0 R4) | Recreates the duplication research condemned; hides recovery away from the step it protects | 2026-07-22 |
| One-time forced re-derivation of all live V2 agents | Changes running production bots without tenant action | 2026-07-22 |
Formal DSAI contract change for resolve (resolve_conversation enum) | Cross-team dependency on DSAI against the standing rule; probe + BE-mint achieves it for free if relay is verbatim | 2026-07-22 |
| Tighten description limit to 4000 | Adds a save-failure mode for existing agents mid-migration; zero user value | 2026-07-22 |
16. Open Questions
| # | Type | Question | Owner | Deadline |
|---|---|---|---|---|
| 1 | Open Question | D3 staging probe result: verbatim relay or enum enforcement? (Determines Resolve in THEN; cut path defined either way) | BOT BE | Before FE builds the THEN dropdown |
| 2 | Open Question | Linter check ⑥ severity: hard-fail or warn on cross-capability exception collision? (Hard-fail is safer; warn is gentler on legacy data) | PM + BOT BE, at RFC | RFC grooming |
| 3 | Assumption | The feat/ai-agents-ut-updates drawer UI passes its pending visual verification without model changes (its docs.md lists browser verification as not yet done) | Design (Wulan) | Before FE build starts |
| 4 | Risk | Derived completion may disagree with a legacy agent's authored completion on first edit — mitigation: D2 messaging ("checkpoints recalculated") + dry-run list gives support the affected orgs before any tenant hits it | BOT BE | Stage 2 entry |
| 5 | Risk | Task test (D6/AISC-S06 AC-3) fails for non-technical users — mitigation: pre-agreed fallback = read-only flow strip (Non-Goal 6 reverses with evidence); does not block Stage 1. Update 2026-07-23: ut-2026-07 de-risks the direction (Steps clearer — Strong) but the non-technical external round is still required | PM (Dimas) | External non-technical round |
| 9 | Risk | Prompt-hierarchy overlap (Goals/Guidance/Instructions/Steps) = the new #1 comprehension risk per ut-2026-07 (Strong; Instructions-vs-Steps redundancy High) — mitigation: hierarchy helper copy in CHG-001 + AISC-S06/AC-4 predictability probe; design brief carries the layer-labeling work | PM + Design (Wulan) | Before the external validation round |
| 10 | Open Question | ut-2026-07 finding 4: Routing "THEN" visually demoted under "WHEN" (rules left half-configured) + capability cards not obviously clickable — both routed to the Wulan change-request brief (THEN gets equal visual weight; clickable signifiers) | Design (Wulan) | Change-request brief |
| 6 | Open Question | fallback constants emission (no_skill_match, turn_budget_exceeded) + reconciling the turn cap with the Rails message_limit Redis counter — kept out of MVP scope; schedule as follow-up ADJUSTMENT? | PM (Dimas) | Post-MVP triage |
| 7 | Open Question | Refine × Steps-model reconciliation (CHG-007 exit): teach SkillPackBuilder + refine_skill_pack_merger the derived model, or route refine through the derivation layer — scoped as the follow-up phase that re-enables Refine for flag-ON orgs | PM (Dimas) + BOT BE | Phase-2 scoping, after MVP GA gate |
PRD CHANGELOG
| Version | Date | By | Section | Type | Summary |
|---|---|---|---|---|---|
| 1.0 | 2026-07-07 | Claude | All | CREATED | Adjustment PRD drafted pre-validation (Downloads draft; milestone-derivation model, Routing-tab Pattern A) |
| 1.1 | 2026-07-22 | Claude | All | REWRITTEN | Rebuilt on the grilled D1–D9 decision register: Steps/SOP model replaces Milestones + Completion (per feat/ai-agents-ut-updates); chain gates from step order; per-step Exceptions = Pattern A home; derive-on-save migration + dry-run; probe-gated resolve; PIH ut-2026-06-23 wired as sources; landed in documents repo |
| 1.2 | 2026-07-22 | Claude | CB, S5, S6, S7 (CHG-007 new), S9.2, S15, S16 | GROUNDED FIXES | From ground-prd assessment (P0/P1/P2): Refine shipped end-to-end → Non-Goal 2 + NEG-02 re-based, Refine disabled for flag-ON orgs (CHG-007), second skill_pack producer scoped; "6-tab" claim corrected (editor already 3-tab, scope right-sized); maxlength=10000 marked net-new enforcement; design-branch exception model restructure specced in AISC-S04; stale file:line anchors + process_async_reply path refreshed; ACTION_LIST duplication named. Plus score-report items: rollback ACs (AISC-S05/AC-4, AISC-S08/AC-5), plan/tier + role-scope + dry-run-retention constraint rows |
| 1.3 | 2026-07-22 | Claude | Header | MODIFIED | Status DRAFT → READY (frontmatter draft → in-review) after 9.0/9.0 all-gates-pass score on the grounded v1.2; PM (Dimas) declared READY 2026-07-22 |
| 1.4 | 2026-07-22 | Claude | Header | MODIFIED | Epic filled: BOT-4733 (child Epic under umbrella BOT-4601, added to README allow-set) |
| 1.5 | 2026-07-22 | Claude | Header | MODIFIED | RFC Link filled: rfcs/simplified-configuration.md (rfc-starter, agent-execution-ready) |
| 1.6 | 2026-07-23 | Claude | Sources, CB, S7 (CHG-001), S9.2 (AISC-S06), S12, S16 | MODIFIED | Grounded on PIH ut-2026-07 (Iteration II UT, merged by Devina): Steps direction validated Strong; prompt-hierarchy overlap = new #1 risk → hierarchy helper copy (CHG-001) + AISC-S06/AC-4 predictability probe + S16 rows 9-10; D6 external non-technical round still the gate; sources + informs wired two-way |