@tencent-rtc/trtc-agent-skills 0.1.0

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 (205) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +172 -0
  3. package/README.zh.md +173 -0
  4. package/bin/cli.js +434 -0
  5. package/knowledge-base/index.yaml +454 -0
  6. package/knowledge-base/platform-slice-template.md +233 -0
  7. package/knowledge-base/scenario-spec.md +350 -0
  8. package/knowledge-base/scenarios/conference/base/general-conference.md +365 -0
  9. package/knowledge-base/scenarios/conference/base/webinar-conference.md +130 -0
  10. package/knowledge-base/scenarios/conference/medical/1v1-video-consultation.md +145 -0
  11. package/knowledge-base/scenarios/conference/medical/medical-multidoctor-consultation.md +113 -0
  12. package/knowledge-base/scenarios/live/entertainment-live-room.md +118 -0
  13. package/knowledge-base/slice-spec.md +546 -0
  14. package/knowledge-base/slices/conference/web/ai-tools.md +225 -0
  15. package/knowledge-base/slices/conference/web/beauty-effects.md +188 -0
  16. package/knowledge-base/slices/conference/web/device-control.md +338 -0
  17. package/knowledge-base/slices/conference/web/login-auth.md +261 -0
  18. package/knowledge-base/slices/conference/web/network-quality.md +190 -0
  19. package/knowledge-base/slices/conference/web/official-roomkit-api.md +298 -0
  20. package/knowledge-base/slices/conference/web/official-roomkit-login-ui.md +246 -0
  21. package/knowledge-base/slices/conference/web/participant-list.md +238 -0
  22. package/knowledge-base/slices/conference/web/participant-management.md +718 -0
  23. package/knowledge-base/slices/conference/web/prejoin-check.md +293 -0
  24. package/knowledge-base/slices/conference/web/room-call.md +213 -0
  25. package/knowledge-base/slices/conference/web/room-chat.md +426 -0
  26. package/knowledge-base/slices/conference/web/room-lifecycle.md +534 -0
  27. package/knowledge-base/slices/conference/web/room-schedule.md +281 -0
  28. package/knowledge-base/slices/conference/web/screen-share.md +211 -0
  29. package/knowledge-base/slices/conference/web/video-layout.md +675 -0
  30. package/knowledge-base/slices/conference/web/virtual-background.md +197 -0
  31. package/knowledge-base/slices/conference/web/webinar-interaction.md +206 -0
  32. package/knowledge-base/slices/live/anchor-lifecycle.md +122 -0
  33. package/knowledge-base/slices/live/anchor-preview.md +90 -0
  34. package/knowledge-base/slices/live/anchor-room-config.md +104 -0
  35. package/knowledge-base/slices/live/audience-list.md +86 -0
  36. package/knowledge-base/slices/live/audience-manage.md +92 -0
  37. package/knowledge-base/slices/live/audience-watch.md +85 -0
  38. package/knowledge-base/slices/live/audio.md +116 -0
  39. package/knowledge-base/slices/live/barrage.md +88 -0
  40. package/knowledge-base/slices/live/beauty.md +99 -0
  41. package/knowledge-base/slices/live/coguest-apply.md +105 -0
  42. package/knowledge-base/slices/live/device-control.md +91 -0
  43. package/knowledge-base/slices/live/error-codes.md +167 -0
  44. package/knowledge-base/slices/live/gift.md +84 -0
  45. package/knowledge-base/slices/live/ios/.gitkeep +0 -0
  46. package/knowledge-base/slices/live/ios/anchor-lifecycle.md +313 -0
  47. package/knowledge-base/slices/live/ios/anchor-preview.md +228 -0
  48. package/knowledge-base/slices/live/ios/anchor-room-config.md +257 -0
  49. package/knowledge-base/slices/live/ios/audience-list.md +353 -0
  50. package/knowledge-base/slices/live/ios/audience-manage.md +381 -0
  51. package/knowledge-base/slices/live/ios/audience-watch.md +286 -0
  52. package/knowledge-base/slices/live/ios/audio.md +373 -0
  53. package/knowledge-base/slices/live/ios/barrage.md +285 -0
  54. package/knowledge-base/slices/live/ios/beauty.md +323 -0
  55. package/knowledge-base/slices/live/ios/coguest-apply.md +506 -0
  56. package/knowledge-base/slices/live/ios/device-control.md +286 -0
  57. package/knowledge-base/slices/live/ios/error-codes.md +270 -0
  58. package/knowledge-base/slices/live/ios/gift.md +315 -0
  59. package/knowledge-base/slices/live/ios/live-list.md +269 -0
  60. package/knowledge-base/slices/live/ios/login-auth.md +247 -0
  61. package/knowledge-base/slices/live/live-list.md +82 -0
  62. package/knowledge-base/slices/live/login-auth.md +78 -0
  63. package/package.json +34 -0
  64. package/skills/trtc/SKILL.md +326 -0
  65. package/skills/trtc/room-builder/SKILL.md +138 -0
  66. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/README.md +108 -0
  67. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/docs/backend-contract.zh-CN.md +162 -0
  68. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/docs/integration.zh-CN.md +154 -0
  69. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/docs/theme.zh-CN.md +78 -0
  70. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/index.html +12 -0
  71. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/package.json +28 -0
  72. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/postcss.config.js +5 -0
  73. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/App.vue +25 -0
  74. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/ConsultationManagePanel.vue +838 -0
  75. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/LanguageSwitch.vue +102 -0
  76. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/LoadingSpinner.vue +6 -0
  77. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/MedicalAlert.vue +34 -0
  78. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/MedicalBusinessPanel.vue +148 -0
  79. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/MedicalButton.vue +49 -0
  80. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/MedicalConfirmDialog.vue +68 -0
  81. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/MedicalDataPanel.vue +196 -0
  82. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/MedicalRecordPanel.vue +270 -0
  83. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/PrescriptionPanel.vue +363 -0
  84. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/config/basic-info-config.ts +29 -0
  85. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/config/lib-generate-test-usersig-es.min.d.ts +4 -0
  86. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/config/lib-generate-test-usersig-es.min.js +2 -0
  87. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/config/runtime-config.ts +12 -0
  88. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/env.d.ts +32 -0
  89. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/components/ConsultationChatPanel.vue +123 -0
  90. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/components/ConsultationMembersPanel.vue +230 -0
  91. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/components/ConsultationTranscriptionPanel.vue +135 -0
  92. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/components/ConsultationVideoStage.vue +113 -0
  93. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/components/InviteDoctorDialog.vue +132 -0
  94. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/components/KickMemberConfirmDialog.vue +50 -0
  95. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/types.ts +77 -0
  96. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/useConsultationChat.ts +97 -0
  97. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/useConsultationDevices.ts +48 -0
  98. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/useConsultationParticipants.ts +121 -0
  99. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/useConsultationPermissions.ts +25 -0
  100. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/utils.ts +70 -0
  101. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/i18n/en-US/index.ts +553 -0
  102. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/i18n/index.ts +25 -0
  103. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/i18n/medicalTranslate.ts +85 -0
  104. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/i18n/state.ts +49 -0
  105. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/i18n/zh-CN/index.ts +463 -0
  106. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/main.ts +12 -0
  107. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/mock/appointments.ts +96 -0
  108. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/mock/users.ts +79 -0
  109. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/router/index.ts +63 -0
  110. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/index.ts +25 -0
  111. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/integration/appointmentService.ts +77 -0
  112. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/integration/authService.ts +38 -0
  113. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/integration/launchContext.ts +31 -0
  114. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/integration/userService.ts +35 -0
  115. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/mock/appointmentService.ts +43 -0
  116. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/mock/authService.ts +33 -0
  117. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/mock/userService.ts +43 -0
  118. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/types.ts +135 -0
  119. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/shared/icons.ts +53 -0
  120. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/styles/index.css +106 -0
  121. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/styles/tailwind.css +3 -0
  122. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/styles/theme.css +209 -0
  123. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/utils/auth.ts +50 -0
  124. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/utils/format.ts +24 -0
  125. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/utils/navigation.ts +12 -0
  126. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/utils/session.ts +28 -0
  127. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/views/DoctorConsultationView.vue +777 -0
  128. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/views/DoctorDashboardView.vue +678 -0
  129. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/views/LoginView.vue +441 -0
  130. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/views/PatientConsultationFinishedView.vue +185 -0
  131. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/views/PatientConsultationView.vue +1003 -0
  132. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/views/PatientSelectDoctorView.vue +317 -0
  133. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/views/PatientWaitingView.vue +454 -0
  134. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/tsconfig.json +21 -0
  135. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/tsconfig.node.json +8 -0
  136. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/vite.config.ts +17 -0
  137. package/skills/trtc/room-builder/templates/scenarios/medical-consultation//346/216/245/345/205/245/350/257/264/346/230/216.md +6 -0
  138. package/skills/trtc/room-builder/tools/render_ai_instructions.py +226 -0
  139. package/skills/trtc-apply/SKILL.md +97 -0
  140. package/skills/trtc-apply/guardrails/apply_lib/__init__.py +0 -0
  141. package/skills/trtc-apply/guardrails/apply_lib/__pycache__/__init__.cpython-313.pyc +0 -0
  142. package/skills/trtc-apply/guardrails/apply_lib/__pycache__/rule_parser.cpython-313.pyc +0 -0
  143. package/skills/trtc-apply/guardrails/apply_lib/rule_parser.py +268 -0
  144. package/skills/trtc-docs/SKILL.md +207 -0
  145. package/skills/trtc-onboarding/SKILL.md +839 -0
  146. package/skills/trtc-onboarding/reference/path-a1-demo.md +103 -0
  147. package/skills/trtc-onboarding/reference/path-a2-integrate.md +693 -0
  148. package/skills/trtc-onboarding/reference/path-b-troubleshoot.md +115 -0
  149. package/skills/trtc-onboarding/reference/path-c-expand.md +43 -0
  150. package/skills/trtc-onboarding/reference/reporting-protocol.md +174 -0
  151. package/skills/trtc-onboarding/reference/supported-matrix.md +100 -0
  152. package/skills/trtc-onboarding/reference/usersig-handling.md +140 -0
  153. package/skills/trtc-search/SKILL.md +221 -0
  154. package/skills/trtc-topic/SKILL.md +638 -0
  155. package/skills/trtc-topic/guardrails/__pycache__/gate_slice_read.cpython-313.pyc +0 -0
  156. package/skills/trtc-topic/guardrails/__pycache__/gate_slice_write.cpython-313.pyc +0 -0
  157. package/skills/trtc-topic/guardrails/__pycache__/stop_require_apply_evidence.cpython-313.pyc +0 -0
  158. package/skills/trtc-topic/guardrails/gate_slice_read.py +133 -0
  159. package/skills/trtc-topic/guardrails/gate_slice_write.py +169 -0
  160. package/skills/trtc-topic/guardrails/stop_require_apply_evidence.py +97 -0
  161. package/skills/trtc-topic/references/execution-units.yaml +58 -0
  162. package/skills/trtc-topic/runtime/README.md +50 -0
  163. package/skills/trtc-topic/runtime/RUNTIME.md +128 -0
  164. package/skills/trtc-topic/runtime/lib/__init__.py +0 -0
  165. package/skills/trtc-topic/runtime/lib/platforms.py +194 -0
  166. package/skills/trtc-topic/runtime/package-lock.json +1211 -0
  167. package/skills/trtc-topic/runtime/package.json +13 -0
  168. package/skills/trtc-topic/runtime/telemetry-bridge.mjs +339 -0
  169. package/skills/trtc-topic/runtime/telemetry_collector.py +293 -0
  170. package/skills/trtc-topic/scripts/STATE-MACHINE-GUIDE.md +186 -0
  171. package/skills/trtc-topic/scripts/__pycache__/apply.cpython-313.pyc +0 -0
  172. package/skills/trtc-topic/scripts/apply.py +581 -0
  173. package/skills/trtc-topic/scripts/finalize_session.py +113 -0
  174. package/skills/trtc-topic/scripts/init_slice_queue.py +96 -0
  175. package/skills/trtc-topic/scripts/lib/__pycache__/state_machine.cpython-313.pyc +0 -0
  176. package/skills/trtc-topic/scripts/lib/state_machine.py +328 -0
  177. package/skills/trtc-topic/scripts/next_slice.py +137 -0
  178. package/skills/trtc-topic/tests/README.md +70 -0
  179. package/skills/trtc-topic/tests/__pycache__/conftest.cpython-313-pytest-9.0.2.pyc +0 -0
  180. package/skills/trtc-topic/tests/__pycache__/conftest.cpython-313-pytest-9.0.3.pyc +0 -0
  181. package/skills/trtc-topic/tests/__pycache__/test_apply_cli.cpython-313-pytest-9.0.2.pyc +0 -0
  182. package/skills/trtc-topic/tests/__pycache__/test_apply_cli.cpython-313-pytest-9.0.3.pyc +0 -0
  183. package/skills/trtc-topic/tests/__pycache__/test_end_to_end.cpython-313-pytest-9.0.2.pyc +0 -0
  184. package/skills/trtc-topic/tests/__pycache__/test_end_to_end.cpython-313-pytest-9.0.3.pyc +0 -0
  185. package/skills/trtc-topic/tests/__pycache__/test_finalize_session.cpython-313-pytest-9.0.2.pyc +0 -0
  186. package/skills/trtc-topic/tests/__pycache__/test_finalize_session.cpython-313-pytest-9.0.3.pyc +0 -0
  187. package/skills/trtc-topic/tests/__pycache__/test_gates.cpython-313-pytest-9.0.2.pyc +0 -0
  188. package/skills/trtc-topic/tests/__pycache__/test_gates.cpython-313-pytest-9.0.3.pyc +0 -0
  189. package/skills/trtc-topic/tests/__pycache__/test_session_resolver.cpython-313-pytest-9.0.2.pyc +0 -0
  190. package/skills/trtc-topic/tests/__pycache__/test_session_resolver.cpython-313-pytest-9.0.3.pyc +0 -0
  191. package/skills/trtc-topic/tests/__pycache__/test_state_machine.cpython-313-pytest-9.0.2.pyc +0 -0
  192. package/skills/trtc-topic/tests/__pycache__/test_state_machine.cpython-313-pytest-9.0.3.pyc +0 -0
  193. package/skills/trtc-topic/tests/__pycache__/test_stop_require_apply.cpython-313-pytest-9.0.2.pyc +0 -0
  194. package/skills/trtc-topic/tests/__pycache__/test_stop_require_apply.cpython-313-pytest-9.0.3.pyc +0 -0
  195. package/skills/trtc-topic/tests/__pycache__/test_topic_skill_invariants.cpython-313-pytest-9.0.2.pyc +0 -0
  196. package/skills/trtc-topic/tests/__pycache__/test_topic_skill_invariants.cpython-313-pytest-9.0.3.pyc +0 -0
  197. package/skills/trtc-topic/tests/conftest.py +72 -0
  198. package/skills/trtc-topic/tests/test_apply_cli.py +480 -0
  199. package/skills/trtc-topic/tests/test_end_to_end.py +305 -0
  200. package/skills/trtc-topic/tests/test_finalize_session.py +51 -0
  201. package/skills/trtc-topic/tests/test_gates.py +316 -0
  202. package/skills/trtc-topic/tests/test_session_resolver.py +260 -0
  203. package/skills/trtc-topic/tests/test_state_machine.py +414 -0
  204. package/skills/trtc-topic/tests/test_stop_require_apply.py +99 -0
  205. package/skills/trtc-topic/tests/test_topic_skill_invariants.py +130 -0
@@ -0,0 +1,99 @@
1
+ """Tests for stop_require_apply_evidence.py — Stop hook.
2
+
3
+ Stop hook runs when the AI's turn ends. We use it to refuse to end on
4
+ states that mean "code was written but not validated":
5
+
6
+ code_written → exit 2 (block) — apply.py never ran
7
+ apply_failed → exit 2 (block) — apply rejected the code, AI must regenerate
8
+
9
+ Other states pass:
10
+ not_started, slice_read, apply_passed, all_done, queue-not-initialised,
11
+ session-missing.
12
+ """
13
+ from __future__ import annotations
14
+
15
+ import subprocess
16
+ import sys
17
+ from pathlib import Path
18
+
19
+ GUARDRAILS_DIR = Path(__file__).resolve().parents[1] / "guardrails"
20
+ STOP_SCRIPT = GUARDRAILS_DIR / "stop_require_apply_evidence.py"
21
+
22
+ STATE_MACHINE_DIR = Path(__file__).resolve().parents[1] / "scripts" / "lib"
23
+ sys.path.insert(0, str(STATE_MACHINE_DIR))
24
+ import state_machine # noqa: E402
25
+ sys.path.pop(0)
26
+
27
+
28
+ def _run(session_path: Path) -> subprocess.CompletedProcess:
29
+ return subprocess.run(
30
+ [sys.executable, str(STOP_SCRIPT)],
31
+ text=True,
32
+ capture_output=True,
33
+ env={"TRTC_SESSION_PATH": str(session_path), "PATH": "/usr/bin:/bin"},
34
+ )
35
+
36
+
37
+ class TestStopHook:
38
+ def test_allows_when_session_missing(self, tmp_path):
39
+ result = _run(tmp_path / "missing.yaml")
40
+ assert result.returncode == 0
41
+
42
+ def test_allows_when_queue_not_initialised(self, session_factory):
43
+ path = session_factory()
44
+ result = _run(path)
45
+ assert result.returncode == 0
46
+
47
+ def test_allows_in_not_started(self, session_factory):
48
+ path = session_factory()
49
+ state_machine.init_queue(path)
50
+ result = _run(path)
51
+ assert result.returncode == 0
52
+
53
+ def test_allows_in_slice_read(self, session_factory):
54
+ path = session_factory()
55
+ state_machine.init_queue(path)
56
+ state_machine.advance(path, "mark_slice_read")
57
+ result = _run(path)
58
+ assert result.returncode == 0
59
+
60
+ def test_blocks_in_code_written(self, session_factory):
61
+ path = session_factory()
62
+ state_machine.init_queue(path)
63
+ state_machine.advance(path, "mark_slice_read")
64
+ state_machine.advance(path, "mark_code_written")
65
+ result = _run(path)
66
+ assert result.returncode == 2
67
+ # Helpful error mentions apply.py and slice id
68
+ assert "apply" in result.stderr.lower()
69
+ assert "login-auth" in result.stderr
70
+
71
+ def test_blocks_in_apply_failed(self, session_factory):
72
+ path = session_factory()
73
+ state_machine.init_queue(path)
74
+ state_machine.advance(path, "mark_slice_read")
75
+ state_machine.advance(path, "mark_code_written")
76
+ state_machine.advance(path, "mark_apply_failed")
77
+ result = _run(path)
78
+ assert result.returncode == 2
79
+ assert "apply_failed" in result.stderr or "regenerate" in result.stderr.lower()
80
+
81
+ def test_allows_in_apply_passed(self, session_factory):
82
+ path = session_factory()
83
+ state_machine.init_queue(path)
84
+ state_machine.advance(path, "mark_slice_read")
85
+ state_machine.advance(path, "mark_code_written")
86
+ state_machine.advance(path, "mark_apply_passed")
87
+ result = _run(path)
88
+ assert result.returncode == 0
89
+
90
+ def test_allows_in_all_done(self, session_factory):
91
+ path = session_factory(confirmed_plan=["conference/login-auth"])
92
+ state_machine.init_queue(path)
93
+ state_machine.advance(path, "mark_slice_read")
94
+ state_machine.advance(path, "mark_code_written")
95
+ state_machine.advance(path, "mark_apply_passed")
96
+ state_machine.advance(path, "mark_user_confirmed")
97
+ # Now in all_done
98
+ result = _run(path)
99
+ assert result.returncode == 0
@@ -0,0 +1,130 @@
1
+ """Topic skill SKILL.md invariants — guards the post-redesign shape.
2
+
3
+ After the topic-skill redesign (2026-05-15), `topic/SKILL.md` was reduced
4
+ from 512 lines to ~390. Four structural invariants survived from that
5
+ work and need to stay true:
6
+
7
+ 1. The "Apply Evidence Block" section was deleted — it instructed AI to
8
+ run its own grep/ls/tsc, duplicating apply.py and giving AI an obvious
9
+ bypass path.
10
+ 2. The State Machine Guide was split out to
11
+ `topic/scripts/STATE-MACHINE-GUIDE.md` and topic/SKILL.md just
12
+ references it.
13
+ 3. The "Calling apply" section is compact — the full request schema lives
14
+ in `apply/SKILL.md` Phase 0; topic only references it.
15
+ 4. topic/SKILL.md size stays within budget so we don't silently re-inline
16
+ the things we split out.
17
+
18
+ Originally this file also enforced the §3.5 cross-skill handoff
19
+ convention ("must use Skill tool, never Read"). That convention was
20
+ walked back on 2026-05-18: the runtime never supported it (sub-skills
21
+ under `trtc/X/` aren't top-level discoverable, so `Skill(skill='trtc-X')`
22
+ returns "Unknown skill"). Plain Read handoff is the only working option
23
+ today. The §3.5-specific tests were removed; this file kept its other
24
+ four invariants. See `docs/topic-skill-long-term-design.md` §10 for the
25
+ walk-back rationale.
26
+ """
27
+ from __future__ import annotations
28
+
29
+ from pathlib import Path
30
+
31
+ import pytest
32
+
33
+ ROOT = Path(__file__).resolve().parents[3] # repo root
34
+ TOPIC_SKILL = ROOT / "skills" / "trtc-topic" / "SKILL.md"
35
+ STATE_MACHINE_GUIDE = (
36
+ ROOT / "skills" / "trtc-topic" / "scripts" / "STATE-MACHINE-GUIDE.md"
37
+ )
38
+ EXECUTION_UNITS = ROOT / "skills" / "trtc-topic" / "references" / "execution-units.yaml"
39
+
40
+
41
+ def test_apply_evidence_block_remains_deleted():
42
+ """Regression: the deleted 'Apply Evidence Block' must not return.
43
+
44
+ Was a multi-paragraph block instructing AI to run its own grep/ls/tsc
45
+ in addition to apply.py. Two-track verification was demo-test-2 root
46
+ cause: AI satisfied one track (the SKILL.md grep) by comment-stuffing
47
+ while apply.py also passed because it ran the same kind of substring
48
+ grep. Single-source verification is enforced by deletion.
49
+ """
50
+ text = TOPIC_SKILL.read_text()
51
+ assert "Apply Evidence Block (MANDATORY" not in text, (
52
+ "topic/SKILL.md still contains 'Apply Evidence Block (MANDATORY' — "
53
+ "this was deleted because it instructed AI to run its own grep, "
54
+ "which duplicates apply.py and AI learned to bypass."
55
+ )
56
+ assert "P1 Imports:" not in text, (
57
+ "topic/SKILL.md still has P1 Imports instruction for AI-run grep"
58
+ )
59
+
60
+
61
+ def test_state_machine_guide_exists_and_is_referenced():
62
+ """The state machine guide must exist and topic/SKILL.md must point to it."""
63
+ assert STATE_MACHINE_GUIDE.exists(), (
64
+ f"State Machine Guide missing at {STATE_MACHINE_GUIDE}. "
65
+ "topic/SKILL.md was reduced under the assumption this guide is split out."
66
+ )
67
+ topic_text = TOPIC_SKILL.read_text()
68
+ assert "STATE-MACHINE-GUIDE.md" in topic_text, (
69
+ "topic/SKILL.md must reference scripts/STATE-MACHINE-GUIDE.md, "
70
+ "otherwise AI has no pointer to the operator's manual."
71
+ )
72
+
73
+
74
+ def test_delivery_unit_grouping_is_declarative():
75
+ """Automatic unit grouping must stay visible outside state_machine.py."""
76
+ assert EXECUTION_UNITS.exists(), "delivery-unit grouping config is missing"
77
+ topic_text = TOPIC_SKILL.read_text()
78
+ guide_text = STATE_MACHINE_GUIDE.read_text()
79
+ assert "references/execution-units.yaml" in topic_text
80
+ assert "references/execution-units.yaml" in guide_text
81
+
82
+ state_machine_text = (
83
+ ROOT / "skills" / "trtc-topic" / "scripts" / "lib" / "state_machine.py"
84
+ ).read_text()
85
+ assert "_DEFAULT_UNIT_GROUPS" not in state_machine_text
86
+ assert "会议基础链路" not in state_machine_text
87
+
88
+
89
+ def test_topic_skill_size_reduced():
90
+ """Sanity check: topic/SKILL.md should be substantially smaller than the
91
+ original 512-line version. If it grows back, something has been re-inlined."""
92
+ text = TOPIC_SKILL.read_text()
93
+ line_count = len(text.splitlines())
94
+ # The topic skill has grown with ui_mode, runtime verification, and
95
+ # delivery-unit execution. Keep a budget so the old anti-patterns don't
96
+ # quietly return, but do not enforce the obsolete 2026-05 compact size.
97
+ assert line_count < 760, (
98
+ f"topic/SKILL.md is {line_count} lines — above the current budget. "
99
+ f"Check if Apply Evidence Block, state machine manual, or Calling apply "
100
+ f"contract was re-inlined."
101
+ )
102
+
103
+
104
+ def test_calling_apply_section_is_compact():
105
+ """The 'Calling apply' section must not contain the removed full request schema.
106
+
107
+ The full I/O contract lives in apply/SKILL.md Phase 0; topic just references it.
108
+ """
109
+ text = TOPIC_SKILL.read_text()
110
+ # Locate the "### Calling apply" section bounds.
111
+ start_marker = "### Calling apply"
112
+ if start_marker not in text:
113
+ pytest.fail("'### Calling apply' section missing from topic/SKILL.md")
114
+ section_start = text.index(start_marker)
115
+ # Section ends at the next '### ' heading.
116
+ after = text[section_start + len(start_marker):]
117
+ next_section_at = after.find("\n### ")
118
+ section_text = after[:next_section_at] if next_section_at >= 0 else after
119
+
120
+ # Mode selection table: should be in apply/SKILL.md only, not in topic.
121
+ bad_markers = [
122
+ "**Mode selection rules:**",
123
+ "**Request construction**",
124
+ "| Situation | mode |",
125
+ ]
126
+ found = [m for m in bad_markers if m in section_text]
127
+ assert not found, (
128
+ f"topic/SKILL.md 'Calling apply' section re-inlined apply request schema "
129
+ f"({found}). Keep the contract in apply/SKILL.md only; topic just references it."
130
+ )