@nac3/forge-cli 0.2.0-alpha.59z.123 → 0.2.0-alpha.59z.158

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/dist/agents/bridge.d.ts +69 -0
  2. package/dist/agents/bridge.d.ts.map +1 -0
  3. package/dist/agents/bridge.js +295 -0
  4. package/dist/agents/bridge.js.map +1 -0
  5. package/dist/agents/cli_real.d.ts +38 -0
  6. package/dist/agents/cli_real.d.ts.map +1 -0
  7. package/dist/agents/cli_real.js +46 -0
  8. package/dist/agents/cli_real.js.map +1 -0
  9. package/dist/agents/config_schema.d.ts +1 -1
  10. package/dist/agents/config_schema.d.ts.map +1 -1
  11. package/dist/agents/config_schema.js +16 -0
  12. package/dist/agents/config_schema.js.map +1 -1
  13. package/dist/agents/defaults.d.ts.map +1 -1
  14. package/dist/agents/defaults.js.map +1 -1
  15. package/dist/agents/delegate.d.ts +36 -0
  16. package/dist/agents/delegate.d.ts.map +1 -0
  17. package/dist/agents/delegate.js +68 -0
  18. package/dist/agents/delegate.js.map +1 -0
  19. package/dist/agents/iterative_step.d.ts +95 -0
  20. package/dist/agents/iterative_step.d.ts.map +1 -0
  21. package/dist/agents/iterative_step.js +249 -0
  22. package/dist/agents/iterative_step.js.map +1 -0
  23. package/dist/agents/llm_step.d.ts +50 -0
  24. package/dist/agents/llm_step.d.ts.map +1 -0
  25. package/dist/agents/llm_step.js +28 -0
  26. package/dist/agents/llm_step.js.map +1 -0
  27. package/dist/agents/real_step_factory.d.ts +95 -0
  28. package/dist/agents/real_step_factory.d.ts.map +1 -0
  29. package/dist/agents/real_step_factory.js +51 -0
  30. package/dist/agents/real_step_factory.js.map +1 -0
  31. package/dist/agents/runner.d.ts +14 -0
  32. package/dist/agents/runner.d.ts.map +1 -1
  33. package/dist/agents/runner.js +10 -1
  34. package/dist/agents/runner.js.map +1 -1
  35. package/dist/agents/runtime.d.ts +115 -0
  36. package/dist/agents/runtime.d.ts.map +1 -0
  37. package/dist/agents/runtime.js +429 -0
  38. package/dist/agents/runtime.js.map +1 -0
  39. package/dist/agents/system_prompt.d.ts +36 -0
  40. package/dist/agents/system_prompt.d.ts.map +1 -0
  41. package/dist/agents/system_prompt.js +101 -0
  42. package/dist/agents/system_prompt.js.map +1 -0
  43. package/dist/agents/types.d.ts +12 -1
  44. package/dist/agents/types.d.ts.map +1 -1
  45. package/dist/agents/types.js.map +1 -1
  46. package/dist/bin/yf.d.ts.map +1 -1
  47. package/dist/bin/yf.js +9 -0
  48. package/dist/bin/yf.js.map +1 -1
  49. package/dist/chat/claude_cli.d.ts +42 -0
  50. package/dist/chat/claude_cli.d.ts.map +1 -0
  51. package/dist/chat/claude_cli.js +299 -0
  52. package/dist/chat/claude_cli.js.map +1 -0
  53. package/dist/chat/graph_snapshot.d.ts +38 -0
  54. package/dist/chat/graph_snapshot.d.ts.map +1 -0
  55. package/dist/chat/graph_snapshot.js +159 -0
  56. package/dist/chat/graph_snapshot.js.map +1 -0
  57. package/dist/chat/ingest_session.d.ts +24 -4
  58. package/dist/chat/ingest_session.d.ts.map +1 -1
  59. package/dist/chat/ingest_session.js +139 -4
  60. package/dist/chat/ingest_session.js.map +1 -1
  61. package/dist/chat/panel.d.ts.map +1 -1
  62. package/dist/chat/panel.js +1358 -0
  63. package/dist/chat/panel.js.map +1 -1
  64. package/dist/chat/server.d.ts +21 -0
  65. package/dist/chat/server.d.ts.map +1 -1
  66. package/dist/chat/server.js +904 -4
  67. package/dist/chat/server.js.map +1 -1
  68. package/dist/chat/tools/nac3_invoke.d.ts +5 -0
  69. package/dist/chat/tools/nac3_invoke.d.ts.map +1 -1
  70. package/dist/chat/tools/nac3_invoke.js +1 -0
  71. package/dist/chat/tools/nac3_invoke.js.map +1 -1
  72. package/dist/chat/tools.d.ts.map +1 -1
  73. package/dist/chat/tools.js +12 -0
  74. package/dist/chat/tools.js.map +1 -1
  75. package/dist/commands/agent.d.ts +12 -1
  76. package/dist/commands/agent.d.ts.map +1 -1
  77. package/dist/commands/agent.js +92 -1
  78. package/dist/commands/agent.js.map +1 -1
  79. package/dist/commands/chat.d.ts +10 -0
  80. package/dist/commands/chat.d.ts.map +1 -1
  81. package/dist/commands/chat.js +12 -1
  82. package/dist/commands/chat.js.map +1 -1
  83. package/dist/commands/director.d.ts +37 -0
  84. package/dist/commands/director.d.ts.map +1 -0
  85. package/dist/commands/director.js +290 -0
  86. package/dist/commands/director.js.map +1 -0
  87. package/dist/core/pilot_setup.d.ts +14 -1
  88. package/dist/core/pilot_setup.d.ts.map +1 -1
  89. package/dist/core/pilot_setup.js +62 -1
  90. package/dist/core/pilot_setup.js.map +1 -1
  91. package/dist/design/yujin_design_resolver.d.ts +77 -0
  92. package/dist/design/yujin_design_resolver.d.ts.map +1 -0
  93. package/dist/design/yujin_design_resolver.js +113 -0
  94. package/dist/design/yujin_design_resolver.js.map +1 -0
  95. package/dist/docs/doctrine/default-design-system.md +120 -0
  96. package/dist/docs/doctrine/language-sovereignty.md +143 -0
  97. package/dist/docs/doctrine/testing-policy.md +211 -0
  98. package/dist/nac3/approval_queue.d.ts +8 -0
  99. package/dist/nac3/approval_queue.d.ts.map +1 -1
  100. package/dist/nac3/approval_queue.js.map +1 -1
  101. package/dist/nac3/internal_manifest.d.ts.map +1 -1
  102. package/dist/nac3/internal_manifest.js +178 -0
  103. package/dist/nac3/internal_manifest.js.map +1 -1
  104. package/dist/office/excel.d.ts +22 -0
  105. package/dist/office/excel.d.ts.map +1 -1
  106. package/dist/office/excel.js +82 -0
  107. package/dist/office/excel.js.map +1 -1
  108. package/dist/qa/brain_matrix/fixtures/scenario_a11y_focus_after_open.json +22 -0
  109. package/dist/qa/brain_matrix/fixtures/scenario_a11y_label_unlabeled_button.json +26 -0
  110. package/dist/qa/brain_matrix/fixtures/scenario_agent_director_consults_workflow_before_dispatch.json +42 -0
  111. package/dist/qa/brain_matrix/fixtures/scenario_analyst_extracts_then_returns.json +28 -0
  112. package/dist/qa/brain_matrix/fixtures/scenario_coder_consults_nac_spec_before_writing.json +28 -0
  113. package/dist/qa/brain_matrix/fixtures/scenario_default_design_system_override_shadcn.json +45 -0
  114. package/dist/qa/brain_matrix/fixtures/scenario_default_design_system_use_card_template.json +44 -0
  115. package/dist/qa/brain_matrix/fixtures/scenario_director_delegates_to_analyst.json +26 -0
  116. package/dist/qa/brain_matrix/fixtures/scenario_director_no_self_delegation.json +20 -0
  117. package/dist/qa/brain_matrix/fixtures/scenario_director_terminal_done_marker.json +19 -0
  118. package/dist/qa/brain_matrix/fixtures/scenario_doctrine_discover_default_design_system.json +50 -0
  119. package/dist/qa/brain_matrix/fixtures/scenario_doctrine_discover_language_sovereignty.json +53 -0
  120. package/dist/qa/brain_matrix/fixtures/scenario_doctrine_discover_testing_policy.json +55 -0
  121. package/dist/qa/brain_matrix/fixtures/scenario_language_sovereignty_not_conducive_spa_python.json +61 -0
  122. package/dist/qa/brain_matrix/fixtures/scenario_language_sovereignty_user_picks_python.json +48 -0
  123. package/dist/qa/brain_matrix/fixtures/scenario_mcp_invoke_destructive_pauses_for_r8.json +42 -0
  124. package/dist/qa/brain_matrix/fixtures/scenario_mcp_invoke_happy_path_writes_pizarron.json +76 -0
  125. package/dist/qa/brain_matrix/fixtures/scenario_mcp_invoke_network_timeout_graceful.json +41 -0
  126. package/dist/qa/brain_matrix/fixtures/scenario_no_hardcoded_color_use_token.json +47 -0
  127. package/dist/qa/brain_matrix/fixtures/scenario_office_excel_update_cell_picks_right_verb.json +26 -0
  128. package/dist/qa/brain_matrix/fixtures/scenario_scaffolder_destructive_pauses_for_approval.json +23 -0
  129. package/dist/qa/brain_matrix/fixtures/scenario_sumie_icon_pick_from_catalog.json +56 -0
  130. package/dist/qa/brain_matrix/fixtures/scenario_tester_uses_shell_exec_only.json +27 -0
  131. package/dist/version.d.ts +1 -1
  132. package/dist/version.js +1 -1
  133. package/dist/workflow/graph.d.ts +59 -0
  134. package/dist/workflow/graph.d.ts.map +1 -0
  135. package/dist/workflow/graph.js +137 -0
  136. package/dist/workflow/graph.js.map +1 -0
  137. package/dist/workflow/state.d.ts +34 -0
  138. package/dist/workflow/state.d.ts.map +1 -1
  139. package/dist/workflow/state.js.map +1 -1
  140. package/docs/doctrine/default-design-system.md +120 -0
  141. package/docs/doctrine/language-sovereignty.md +143 -0
  142. package/docs/doctrine/testing-policy.md +211 -0
  143. package/package.json +102 -100
  144. package/src/i18n/catalogs/ar.json +20 -1
  145. package/src/i18n/catalogs/de.json +20 -1
  146. package/src/i18n/catalogs/en.json +20 -21
  147. package/src/i18n/catalogs/es.json +20 -21
  148. package/src/i18n/catalogs/fr.json +20 -1
  149. package/src/i18n/catalogs/hi.json +20 -1
  150. package/src/i18n/catalogs/it.json +20 -1
  151. package/src/i18n/catalogs/ja.json +20 -1
  152. package/src/i18n/catalogs/pt.json +20 -1
  153. package/src/i18n/catalogs/zh.json +20 -1
  154. package/templates/sumi-context.template.md +57 -0
@@ -0,0 +1,26 @@
1
+ {
2
+ "id": "a11y_label_unlabeled_button",
3
+ "description": "F107 closure -- when the user reports that a button does not announce its purpose to a screen reader (icon-only button, missing aria-label), the brain calls yujin.a11y.label with a descriptive aria-label + optional shortcut hint. NOT a generic styling fix, NOT a write to the source code (the verb mutates the live DOM via aria attributes).",
4
+ "setup": {
5
+ "extra_system_prompt": "A11Y VERBS active:\n- yujin.a11y.label args:{slug<required>, description<required>, shortcut?, role?}\nIcon-only buttons need an aria-label so screen-reader users hear the purpose. Use a11y.label to attach the missing description; do NOT modify the source code (yujin.fs.write-project-file) for runtime ARIA fixes."
6
+ },
7
+ "turns": [
8
+ { "kind": "user_says", "text": "El boton del icono de imprimir no anuncia nada al lector. Ponele label \"Imprimir reporte\"" }
9
+ ],
10
+ "invariants": [
11
+ { "name": "uses_a11y_label", "kind": "verb_invoked", "params": { "verb_id": "yujin.a11y.label" } },
12
+ { "name": "no_source_edit", "kind": "verb_not_invoked", "params": { "verb_id": "yujin.fs.write-project-file" } },
13
+ { "name": "no_invent_verbs", "kind": "no_invent_verb", "params": {} }
14
+ ],
15
+ "fake_responses": [
16
+ {
17
+ "text": "Le pongo la label.",
18
+ "tool_calls": [
19
+ { "name": "nac3_invoke", "args": { "verb_id": "yujin.a11y.label", "args": { "slug": "toolbar.print-button", "description": "Imprimir reporte" } } }
20
+ ]
21
+ },
22
+ {
23
+ "text": "Listo, ahora el lector anuncia 'Imprimir reporte' al enfocar el boton."
24
+ }
25
+ ]
26
+ }
@@ -0,0 +1,42 @@
1
+ {
2
+ "id": "agent_director_consults_workflow_before_dispatch",
3
+ "description": "When the Director receives a build ask, validates it reads workflow.language_choices BEFORE delegating to coder.",
4
+ "setup": {},
5
+ "turns": [
6
+ {
7
+ "kind": "user_says",
8
+ "text": "Arranca a generar el endpoint POST /orders."
9
+ }
10
+ ],
11
+ "invariants": [
12
+ {
13
+ "name": "no_invent_verbs",
14
+ "kind": "no_invent_verb",
15
+ "params": {}
16
+ },
17
+ {
18
+ "name": "reads_workflow_first",
19
+ "kind": "verb_invoked",
20
+ "params": {
21
+ "verb_id": "yujin.workflow.state"
22
+ }
23
+ }
24
+ ],
25
+ "fake_responses": [
26
+ {
27
+ "text": "Consulto el state actual del workflow para saber el lenguaje elegido.",
28
+ "tool_calls": [
29
+ {
30
+ "name": "nac3_invoke",
31
+ "args": {
32
+ "verb_id": "yujin.workflow.state",
33
+ "args": {}
34
+ }
35
+ }
36
+ ]
37
+ },
38
+ {
39
+ "text": "backend=ts segun language_choices. Genero el endpoint en TypeScript."
40
+ }
41
+ ]
42
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "id": "analyst_extracts_then_returns",
3
+ "description": "Director live execution -- Analyst sub-agent receives a delegated payload (extract requirements from docA). It reads sections via yujin.reader.read-section + returns a structured summary in text. Validates Analyst stays within its narrow verb scope and produces last_reply text the Director can consume.",
4
+ "setup": {
5
+ "extra_system_prompt": "ANALYST ROLE active. Your allowed verbs are yujin.reader.read-section + yujin.workflow.state. Read the requested sections, then return a structured summary (entities, endpoints, constraints). Do NOT delegate, scaffold, or run shell -- those are other roles.\n\nVerbs:\n- yujin.reader.read-section [u s] args:{doc_id<required>, section_id<required>}\n- yujin.workflow.state [u s] args:{}"
6
+ },
7
+ "turns": [
8
+ { "kind": "user_says", "text": "Extrae los requisitos del spec docA seccion sec-1." }
9
+ ],
10
+ "invariants": [
11
+ { "name": "reads_section", "kind": "verb_invoked", "params": { "verb_id": "yujin.reader.read-section" } },
12
+ { "name": "no_delegate", "kind": "verb_not_invoked", "params": { "verb_id": "yujin.agent.delegate" } },
13
+ { "name": "no_fs_write", "kind": "verb_not_invoked", "params": { "verb_id": "yujin.fs.write-project-file" } },
14
+ { "name": "returns_structured", "kind": "text_contains_any", "params": { "substrs": ["requisitos", "requirements", "entidades", "entities", "endpoints", "lista"] } },
15
+ { "name": "no_invent_verbs", "kind": "no_invent_verb", "params": {} }
16
+ ],
17
+ "fake_responses": [
18
+ {
19
+ "text": "Leo la seccion solicitada.",
20
+ "tool_calls": [
21
+ { "name": "nac3_invoke", "args": { "verb_id": "yujin.reader.read-section", "args": { "doc_id": "docA", "section_id": "sec-1" } } }
22
+ ]
23
+ },
24
+ {
25
+ "text": "Extraje los requirements de sec-1: entidades [Lead, Order], endpoints [POST /api/lead]. Listo."
26
+ }
27
+ ]
28
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "id": "coder_consults_nac_spec_before_writing",
3
+ "description": "Director live execution -- Coder is told to write a new feature. Before invoking yujin.fs.write-project-file (which is destructive + would pause for approval), it consults yujin.consult.nac-spec to verify the verb shape it intends to use. Validates the consult-before-act pattern + first-tool ordering.",
4
+ "setup": {
5
+ "extra_system_prompt": "CODER ROLE active. Before scaffolding a NAC3-related feature, ALWAYS consult yujin.consult.nac-spec to verify the verb / atributos shape. Only then invoke yujin.fs.write-project-file (destructive -- the modal will fire).\n\nVerbs:\n- yujin.consult.nac-spec [u s] args:{topic<required>}\n- yujin.fs.write-project-file [u d] args:{path<required>, body<required>}"
6
+ },
7
+ "turns": [
8
+ { "kind": "user_says", "text": "Agregame un button NAC3 nuevo en components/Foo.tsx para abrir el pizarron." }
9
+ ],
10
+ "invariants": [
11
+ { "name": "consult_first", "kind": "verb_invoked_in_order", "params": { "sequence": ["yujin.consult.nac-spec", "yujin.fs.write-project-file"] } },
12
+ { "name": "no_invent_verbs", "kind": "no_invent_verb", "params": {} }
13
+ ],
14
+ "fake_responses": [
15
+ {
16
+ "text": "Primero verifico la shape NAC3 del button.",
17
+ "tool_calls": [
18
+ { "name": "nac3_invoke", "args": { "verb_id": "yujin.consult.nac-spec", "args": { "topic": "data-nac-action button pizarron.open" } } }
19
+ ]
20
+ },
21
+ {
22
+ "text": "Ahora escribo el componente.",
23
+ "tool_calls": [
24
+ { "name": "nac3_invoke", "args": { "verb_id": "yujin.fs.write-project-file", "args": { "path": "components/Foo.tsx", "body": "// new button" } } }
25
+ ]
26
+ }
27
+ ]
28
+ }
@@ -0,0 +1,45 @@
1
+ {
2
+ "id": "default_design_system_override_shadcn",
3
+ "description": "User explicitly requests a non-Yujin DS. Validates Director invokes override (approval_required).",
4
+ "setup": {},
5
+ "turns": [
6
+ {
7
+ "kind": "user_says",
8
+ "text": "Para este proyecto usa shadcn/ui en lugar de Yujin DS."
9
+ }
10
+ ],
11
+ "invariants": [
12
+ {
13
+ "name": "no_invent_verbs",
14
+ "kind": "no_invent_verb",
15
+ "params": {}
16
+ },
17
+ {
18
+ "name": "invokes_override",
19
+ "kind": "verb_invoked",
20
+ "params": {
21
+ "verb_id": "yujin.design.override"
22
+ }
23
+ }
24
+ ],
25
+ "fake_responses": [
26
+ {
27
+ "text": "Voy a abrir el modal de override (R8). Confirma en el modal.",
28
+ "tool_calls": [
29
+ {
30
+ "name": "nac3_invoke",
31
+ "args": {
32
+ "verb_id": "yujin.design.override",
33
+ "args": {
34
+ "system_id": "shadcn",
35
+ "reason": "user explicit request"
36
+ }
37
+ }
38
+ }
39
+ ]
40
+ },
41
+ {
42
+ "text": "[NAC3 modal] APPROVED. Override persistido. A partir de ahora uso shadcn."
43
+ }
44
+ ]
45
+ }
@@ -0,0 +1,44 @@
1
+ {
2
+ "id": "default_design_system_use_card_template",
3
+ "description": "User asks for a component. Validates Coder fetches the Yujin template instead of inventing CSS.",
4
+ "setup": {},
5
+ "turns": [
6
+ {
7
+ "kind": "user_says",
8
+ "text": "Necesito una card para mostrar productos."
9
+ }
10
+ ],
11
+ "invariants": [
12
+ {
13
+ "name": "no_invent_verbs",
14
+ "kind": "no_invent_verb",
15
+ "params": {}
16
+ },
17
+ {
18
+ "name": "uses_yujin_template",
19
+ "kind": "verb_invoked",
20
+ "params": {
21
+ "verb_id": "yujin.design.get-template"
22
+ }
23
+ }
24
+ ],
25
+ "fake_responses": [
26
+ {
27
+ "text": "Traigo el template Yujin de card.",
28
+ "tool_calls": [
29
+ {
30
+ "name": "nac3_invoke",
31
+ "args": {
32
+ "verb_id": "yujin.design.get-template",
33
+ "args": {
34
+ "slug": "card"
35
+ }
36
+ }
37
+ }
38
+ ]
39
+ },
40
+ {
41
+ "text": "Listo, aca esta el template de yj-card con tokens del Design System."
42
+ }
43
+ ]
44
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "id": "director_delegates_to_analyst",
3
+ "description": "Director live execution -- Director receives a spec and decides to dispatch the Analyst sub-agent via yujin.agent.delegate, NOT a direct nac3 read/write. Validates that the iterative_step + brain understand inter-agent delegation as a first-class verb.",
4
+ "setup": {
5
+ "extra_system_prompt": "DIRECTOR ROLE active. You are the orchestrator. Delegate spec extraction to the Analyst sub-agent via yujin.agent.delegate {to_slug: 'analyst', payload, tokens_used}. Do NOT call reader/pizarron verbs directly -- those are Analyst's job.\n\nAvailable verbs:\n- yujin.agent.delegate [u s] args:{to_slug<required>, payload<required>, tokens_used?}"
6
+ },
7
+ "turns": [
8
+ { "kind": "user_says", "text": "Extrae los requisitos del spec docA. Pasalo al equipo." }
9
+ ],
10
+ "invariants": [
11
+ { "name": "delegates_to_analyst", "kind": "verb_invoked", "params": { "verb_id": "yujin.agent.delegate" } },
12
+ { "name": "no_direct_reader", "kind": "verb_not_invoked", "params": { "verb_id": "yujin.reader.read-section" } },
13
+ { "name": "no_invent_verbs", "kind": "no_invent_verb", "params": {} }
14
+ ],
15
+ "fake_responses": [
16
+ {
17
+ "text": "Delego a Analyst.",
18
+ "tool_calls": [
19
+ { "name": "nac3_invoke", "args": { "verb_id": "yujin.agent.delegate", "args": { "to_slug": "analyst", "payload": "extract spec docA requirements", "tokens_used": 25 } } }
20
+ ]
21
+ },
22
+ {
23
+ "text": "Analyst returned the plan. Listo."
24
+ }
25
+ ]
26
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "id": "director_no_self_delegation",
3
+ "description": "Director live execution -- delegations are LATERAL: dispatch to another role's slug (analyst / coder / tester / scaffolder), never to_slug='director'. The bridge ACL would reject a self-loop. Validates the brain answers without invoking yujin.agent.delegate at all when the user's request is something the director itself can handle.",
4
+ "setup": {
5
+ "extra_system_prompt": "DIRECTOR ROLE active. Delegations are LATERAL -- you call analyst / coder / tester / scaffolder. NEVER call to_slug='director' (self-loop -- the bridge ACL rejects it). When a task is reasoning-only (no spec extraction, no code generation, no fs writes), handle it yourself without delegating.\n\nVerbs:\n- yujin.agent.delegate [u s] args:{to_slug<required>, payload<required>}"
6
+ },
7
+ "turns": [
8
+ { "kind": "user_says", "text": "Hazme un breakdown de los siguientes 3 pasos en texto, sin tools." }
9
+ ],
10
+ "invariants": [
11
+ { "name": "no_delegate_for_text_only", "kind": "verb_not_invoked", "params": { "verb_id": "yujin.agent.delegate" } },
12
+ { "name": "no_invent_verbs", "kind": "no_invent_verb", "params": {} },
13
+ { "name": "answers_with_steps", "kind": "text_contains_any", "params": { "substrs": ["1", "primero", "step 1", "paso 1", "1)", "1.", "2.", "2)"] } }
14
+ ],
15
+ "fake_responses": [
16
+ {
17
+ "text": "Breakdown directo, sin delegar: 1) Parsear spec. 2) Listar entidades. 3) Priorizar slices."
18
+ }
19
+ ]
20
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "id": "director_terminal_done_marker",
3
+ "description": "Director live execution -- when the orchestrator finishes a multi-step plan and there is nothing left, the assistant emits a clear terminal marker ('[DONE]' / 'listo' / 'terminado') so the iterative_step's done detector concludes the run. Validates the terminal-marker pathway.",
4
+ "setup": {
5
+ "extra_system_prompt": "DIRECTOR ROLE active. When all sub-agents have returned + the plan is closed, emit a clear terminal marker. Acceptable forms: '[DONE]', 'listo.', 'terminado.', 'todo listo.' -- in any locale you have already adopted. Do NOT keep delegating once the goal is met."
6
+ },
7
+ "turns": [
8
+ { "kind": "user_says", "text": "Confirma que el sprint X ya esta cerrado." }
9
+ ],
10
+ "invariants": [
11
+ { "name": "emits_terminal", "kind": "regex_match", "params": { "pattern": "(\\[DONE\\]|\\blisto\\b|\\bterminado\\b|todo listo)" } },
12
+ { "name": "no_extra_delegates", "kind": "verb_not_invoked", "params": { "verb_id": "yujin.agent.delegate" } }
13
+ ],
14
+ "fake_responses": [
15
+ {
16
+ "text": "Sprint X cerrado. Todos los sub-agentes devolvieron OK. [DONE]"
17
+ }
18
+ ]
19
+ }
@@ -0,0 +1,50 @@
1
+ {
2
+ "id": "doctrine_discover_default_design_system",
3
+ "description": "Brain is asked about the default design system doctrine. Validates discovery or direct answer.",
4
+ "setup": {},
5
+ "turns": [
6
+ {
7
+ "kind": "user_says",
8
+ "text": "Cual es el design system por default de Forge?"
9
+ }
10
+ ],
11
+ "invariants": [
12
+ {
13
+ "name": "no_invent_verbs",
14
+ "kind": "no_invent_verb",
15
+ "params": {}
16
+ },
17
+ {
18
+ "name": "mentions_yujin_ds",
19
+ "kind": "text_contains_any",
20
+ "params": {
21
+ "substrs": [
22
+ "Yujin Design System",
23
+ "Yujin DS",
24
+ "yujin.design"
25
+ ]
26
+ }
27
+ }
28
+ ],
29
+ "fake_responses": [
30
+ {
31
+ "text": "Traigo la doctrina de design system.",
32
+ "tool_calls": [
33
+ {
34
+ "name": "nac3_invoke",
35
+ "args": {
36
+ "verb_id": "yujin.doctrine.discover",
37
+ "args": {
38
+ "slugs": [
39
+ "default-design-system"
40
+ ]
41
+ }
42
+ }
43
+ }
44
+ ]
45
+ },
46
+ {
47
+ "text": "El default es Yujin Design System (30 componentes, 258 tokens DTCG, 170 sumi-e). Override via yujin.design.override (R8 modal)."
48
+ }
49
+ ]
50
+ }
@@ -0,0 +1,53 @@
1
+ {
2
+ "id": "doctrine_discover_language_sovereignty",
3
+ "description": "Brain is asked about language choice doctrine. Validates discovery via yujin.doctrine.discover OR direct in-prompt answer using the language-sovereignty rule.",
4
+ "setup": {},
5
+ "turns": [
6
+ {
7
+ "kind": "user_says",
8
+ "text": "Que dice la doctrina sobre eleccion de lenguaje de programacion?"
9
+ }
10
+ ],
11
+ "invariants": [
12
+ {
13
+ "name": "no_invent_verbs",
14
+ "kind": "no_invent_verb",
15
+ "params": {}
16
+ },
17
+ {
18
+ "name": "mentions_sovereignty",
19
+ "kind": "text_contains_any",
20
+ "params": {
21
+ "substrs": [
22
+ "user",
23
+ "usuario",
24
+ "pick",
25
+ "elige",
26
+ "language",
27
+ "sovereignty"
28
+ ]
29
+ }
30
+ }
31
+ ],
32
+ "fake_responses": [
33
+ {
34
+ "text": "Traigo la doctrina de language sovereignty.",
35
+ "tool_calls": [
36
+ {
37
+ "name": "nac3_invoke",
38
+ "args": {
39
+ "verb_id": "yujin.doctrine.discover",
40
+ "args": {
41
+ "slugs": [
42
+ "language-sovereignty"
43
+ ]
44
+ }
45
+ }
46
+ }
47
+ ]
48
+ },
49
+ {
50
+ "text": "Per docs/doctrine/language-sovereignty.md: el user picks the language; el Director suggests but never imposes. Si el lenguaje no es conducente para el componente, Director responde con la tabla."
51
+ }
52
+ ]
53
+ }
@@ -0,0 +1,55 @@
1
+ {
2
+ "id": "doctrine_discover_testing_policy",
3
+ "description": "Brain is asked about TDD policy. Validates discovery or direct answer about TDD-first scope.",
4
+ "setup": {},
5
+ "turns": [
6
+ {
7
+ "kind": "user_says",
8
+ "text": "Cuando hago TDD primero y cuando codigo primero en Forge?"
9
+ }
10
+ ],
11
+ "invariants": [
12
+ {
13
+ "name": "no_invent_verbs",
14
+ "kind": "no_invent_verb",
15
+ "params": {}
16
+ },
17
+ {
18
+ "name": "mentions_tdd_scope",
19
+ "kind": "text_contains_any",
20
+ "params": {
21
+ "substrs": [
22
+ "TDD",
23
+ "tests first",
24
+ "red",
25
+ "green",
26
+ "opt-in",
27
+ "backend",
28
+ "API",
29
+ "transformer"
30
+ ]
31
+ }
32
+ }
33
+ ],
34
+ "fake_responses": [
35
+ {
36
+ "text": "Traigo la doctrina de testing-policy.",
37
+ "tool_calls": [
38
+ {
39
+ "name": "nac3_invoke",
40
+ "args": {
41
+ "verb_id": "yujin.doctrine.discover",
42
+ "args": {
43
+ "slugs": [
44
+ "testing-policy"
45
+ ]
46
+ }
47
+ }
48
+ }
49
+ ]
50
+ },
51
+ {
52
+ "text": "TDD-first es opt-in. Lo uses en backend/API/transformer/financial/integration; code-first en UI/exploratory."
53
+ }
54
+ ]
55
+ }
@@ -0,0 +1,61 @@
1
+ {
2
+ "id": "language_sovereignty_not_conducive_spa_python",
3
+ "description": "User requests Python for SPA frontend. Validates Director responds with the table row + DOES NOT switch.",
4
+ "setup": {},
5
+ "turns": [
6
+ {
7
+ "kind": "user_says",
8
+ "text": "Quiero el frontend SPA en Python."
9
+ }
10
+ ],
11
+ "invariants": [
12
+ {
13
+ "name": "no_invent_verbs",
14
+ "kind": "no_invent_verb",
15
+ "params": {}
16
+ },
17
+ {
18
+ "name": "explains_not_conducive",
19
+ "kind": "text_contains_any",
20
+ "params": {
21
+ "substrs": [
22
+ "no es conducente",
23
+ "not conducive",
24
+ "browser",
25
+ "navegador",
26
+ "runtime",
27
+ "TS",
28
+ "JS"
29
+ ]
30
+ }
31
+ },
32
+ {
33
+ "name": "no_silent_switch",
34
+ "kind": "verb_not_invoked",
35
+ "params": {
36
+ "verb_id": "yujin.workflow.set"
37
+ }
38
+ }
39
+ ],
40
+ "fake_responses": [
41
+ {
42
+ "text": "Voy a consultar la doctrina antes de responder.",
43
+ "tool_calls": [
44
+ {
45
+ "name": "nac3_invoke",
46
+ "args": {
47
+ "verb_id": "yujin.doctrine.discover",
48
+ "args": {
49
+ "slugs": [
50
+ "language-sovereignty"
51
+ ]
52
+ }
53
+ }
54
+ }
55
+ ]
56
+ },
57
+ {
58
+ "text": "Python no es conducente para un SPA frontend porque no es runtime del navegador. Las opciones validas son: TS, JS, WASM target (Rust, Go). Cual preferis?"
59
+ }
60
+ ]
61
+ }
@@ -0,0 +1,48 @@
1
+ {
2
+ "id": "language_sovereignty_user_picks_python",
3
+ "description": "User declares a language preference. Validates Director switches via yujin.workflow.set.",
4
+ "setup": {},
5
+ "turns": [
6
+ {
7
+ "kind": "user_says",
8
+ "text": "Quiero el backend en Python con FastAPI."
9
+ }
10
+ ],
11
+ "invariants": [
12
+ {
13
+ "name": "no_invent_verbs",
14
+ "kind": "no_invent_verb",
15
+ "params": {}
16
+ },
17
+ {
18
+ "name": "persists_choice",
19
+ "kind": "verb_invoked",
20
+ "params": {
21
+ "verb_id": "yujin.workflow.set"
22
+ }
23
+ }
24
+ ],
25
+ "fake_responses": [
26
+ {
27
+ "text": "Listo, backend en Python. Persisto la decision.",
28
+ "tool_calls": [
29
+ {
30
+ "name": "nac3_invoke",
31
+ "args": {
32
+ "verb_id": "yujin.workflow.set",
33
+ "args": {
34
+ "path": "language_choices.backend",
35
+ "value": {
36
+ "lang": "python",
37
+ "decided_by": "user"
38
+ }
39
+ }
40
+ }
41
+ }
42
+ ]
43
+ },
44
+ {
45
+ "text": "Backend en Python guardado."
46
+ }
47
+ ]
48
+ }
@@ -0,0 +1,42 @@
1
+ {
2
+ "id": "mcp_invoke_destructive_pauses_for_r8",
3
+ "description": "F101 slice 6 -- the brain invokes a destructive tool from a remote MCP bridge (crm.delete_contact). The dispatcher returns nac3_panel_approval_required envelope (same shape the panel modal subscribes to for native NAC-3 destructive verbs). The brain acknowledges the modal + does NOT retry the invoke in the same turn. Locks the MCP path through the unified R8 destructive-always-confirm gate.",
4
+ "setup": {
5
+ "expose_mcp_verbs": true,
6
+ "extra_system_prompt": "ACTIVE MCP BRIDGES (already discovered in session):\n- bridge crm: enabled, auth_loaded=true, tools include destructive delete_contact (policy=destructive, requires R8).\n\nWhen you invoke a destructive remote tool, the dispatcher fires the same panel R8 modal as native NAC-3 verbs. After the envelope returns nac3_panel_approval_required=true, your turn ENDS -- do NOT retry. The user resolves via the modal."
7
+ },
8
+ "turns": [
9
+ { "kind": "user_says", "text": "Borra el contacto id=42 del CRM" },
10
+ {
11
+ "kind": "tool_result",
12
+ "tool_name": "yujin.mcp.invoke-tool",
13
+ "is_error": false,
14
+ "result": {
15
+ "nac3_panel_approval_required": true,
16
+ "trace_id": "tr-mcp-7",
17
+ "verb": "yujin.mcp.invoke-tool",
18
+ "args": { "bridge_id": "crm", "tool_slug": "delete_contact", "args": { "id": 42 } },
19
+ "remote_policy": "destructive",
20
+ "bridge_id": "crm",
21
+ "tool_slug": "delete_contact"
22
+ }
23
+ }
24
+ ],
25
+ "invariants": [
26
+ { "name": "uses_invoke_tool", "kind": "verb_invoked", "params": { "verb_id": "yujin.mcp.invoke-tool" } },
27
+ { "name": "no_invent_verbs", "kind": "no_invent_verb", "params": {} },
28
+ { "name": "acknowledges_modal", "kind": "text_contains_any", "params": { "substrs": ["modal", "approval", "aprobar", "espera", "espero", "pending", "confirmacion", "confirmar"] } },
29
+ { "name": "no_retry_after_modal", "kind": "max_tool_calls", "params": { "n": 1 } }
30
+ ],
31
+ "fake_responses": [
32
+ {
33
+ "text": "Tool destructive. Abro el modal R8 antes de borrar.",
34
+ "tool_calls": [
35
+ { "name": "nac3_invoke", "args": { "verb_id": "yujin.mcp.invoke-tool", "args": { "bridge_id": "crm", "tool_slug": "delete_contact", "args": { "id": 42 } } } }
36
+ ]
37
+ },
38
+ {
39
+ "text": "El modal de approval esta abierto. Espero a que confirmes para ejecutar el borrado."
40
+ }
41
+ ]
42
+ }