@tencent-rtc/trtc-agent-skills 0.1.3 → 0.1.4
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.
- package/.cursor/rules/main.mdc +12 -0
- package/AGENTS.md +14 -104
- package/CLAUDE.md +15 -127
- package/CODEBUDDY.md +32 -118
- package/README.md +7 -5
- package/README.zh.md +7 -5
- package/bin/cli.js +133 -41
- package/hooks/__pycache__/cursor-adapter.cpython-313.pyc +0 -0
- package/hooks/cursor-adapter.py +45 -18
- package/hooks/hooks-cursor.json +5 -18
- package/hooks/hooks.json +6 -31
- package/knowledge-base/conference/web/index.yaml +143 -0
- package/knowledge-base/platform-slice-template.md +1041 -133
- package/knowledge-base/products.yaml +76 -0
- package/knowledge-base/scenario-spec.md +1316 -115
- package/knowledge-base/scenarios/conference/base/general-conference.md +22 -2
- package/knowledge-base/scenarios/conference/base/webinar-conference.md +14 -0
- package/knowledge-base/scenarios/conference/medical/1v1-video-consultation.md +19 -0
- package/knowledge-base/scenarios/conference/medical/medical-multidoctor-consultation.md +13 -0
- package/knowledge-base/scenarios/live/entertainment-live-room.md +12 -0
- package/knowledge-base/slice-spec.md +2377 -299
- package/knowledge-base/slices/conference/web/integration-audit.md +1 -1
- package/knowledge-base/slices/conference/web/login-auth.md +14 -1
- package/knowledge-base/tooling/aliases.yaml +92 -0
- package/knowledge-base/tooling/intent-signals.yaml +181 -0
- package/knowledge-base/tooling/symptom-keywords.yaml +21 -0
- package/package.json +1 -1
- package/skills/trtc/SKILL.md +202 -245
- package/skills/trtc/hooks/__pycache__/report_prompt.cpython-313.pyc +0 -0
- package/skills/{trtc-topic/guardrails → trtc/hooks}/gate_slice_read.py +12 -8
- package/skills/{trtc-topic/guardrails → trtc/hooks}/gate_slice_write.py +16 -12
- package/skills/{trtc-topic/guardrails → trtc/hooks}/stop_require_apply_evidence.py +22 -14
- package/skills/trtc/hooks/topic_phase_gate.py +161 -0
- package/skills/{trtc-topic → trtc}/runtime/README.md +2 -2
- package/skills/{trtc-onboarding/reference/reporting-protocol.md → trtc/runtime/REPORTING.md} +5 -5
- package/skills/{trtc-topic → trtc}/runtime/RUNTIME.md +5 -5
- package/skills/trtc/runtime/lib/__init__.py +0 -0
- package/skills/{trtc-topic → trtc}/runtime/package-lock.json +2 -2
- package/skills/{trtc-topic → trtc}/runtime/package.json +2 -2
- package/skills/{trtc-topic → trtc}/runtime/telemetry-bridge.mjs +1 -1
- package/skills/{trtc-topic/scripts → trtc/tools}/STATE-MACHINE-GUIDE.md +23 -23
- package/skills/trtc/tools/__init__.py +2 -0
- package/skills/trtc/tools/__pycache__/__init__.cpython-313.pyc +0 -0
- package/skills/trtc/tools/__pycache__/query_classifier.cpython-313.pyc +0 -0
- package/skills/trtc/tools/__pycache__/reporting.cpython-313.pyc +0 -0
- package/skills/trtc/tools/__pycache__/search.cpython-313.pyc +0 -0
- package/skills/trtc/tools/__pycache__/session.cpython-313.pyc +0 -0
- package/skills/trtc/tools/apply.py +540 -0
- package/skills/trtc/tools/docs.py +712 -0
- package/skills/trtc/tools/docsbot.py +182 -0
- package/skills/trtc/tools/entry/render_ai_instructions.py +92 -0
- package/skills/trtc/tools/flow.py +1089 -0
- package/skills/{trtc-topic/scripts → trtc/tools}/init_slice_queue.py +5 -4
- package/skills/{trtc-topic/scripts → trtc/tools}/next_slice.py +5 -4
- package/skills/trtc/tools/query_classifier.py +301 -0
- package/skills/trtc/tools/reporting.py +447 -0
- package/skills/trtc/tools/search.py +817 -0
- package/skills/trtc/tools/session.py +1261 -0
- package/skills/trtc/tools/state_machine.py +690 -0
- package/skills/trtc-ai-service/README.md +195 -0
- package/skills/trtc-ai-service/README.zh-CN.md +193 -0
- package/skills/trtc-ai-service/SKILL.md +945 -0
- package/skills/trtc-ai-service/auto_adapters/README.md +40 -0
- package/skills/trtc-ai-service/auto_adapters/frontend-spa/README.md +27 -0
- package/skills/trtc-ai-service/auto_adapters/frontend-spa/angular/voice-agent.component.ts.tpl +131 -0
- package/skills/trtc-ai-service/auto_adapters/frontend-spa/manifest.yaml +57 -0
- package/skills/trtc-ai-service/auto_adapters/frontend-spa/react/VoiceAgent.tsx.tpl +142 -0
- package/skills/trtc-ai-service/auto_adapters/frontend-spa/vue/VoiceAgent.vue.tpl +121 -0
- package/skills/trtc-ai-service/auto_adapters/integration_templates/generic-backend.md +45 -0
- package/skills/trtc-ai-service/auto_adapters/integration_templates/generic-frontend.md +51 -0
- package/skills/trtc-ai-service/auto_adapters/integration_templates/generic-rest-api.md +93 -0
- package/skills/trtc-ai-service/auto_adapters/java-backend/README.md +25 -0
- package/skills/trtc-ai-service/auto_adapters/java-backend/manifest.yaml +30 -0
- package/skills/trtc-ai-service/auto_adapters/java-backend/quarkus/VoiceAgentFilter.java.tpl +64 -0
- package/skills/trtc-ai-service/auto_adapters/java-backend/springboot/VoiceAgentFilter.java.tpl +91 -0
- package/skills/trtc-ai-service/auto_adapters/manifest.yaml +43 -0
- package/skills/trtc-ai-service/auto_adapters/node-backend/README.md +25 -0
- package/skills/trtc-ai-service/auto_adapters/node-backend/express.js.tpl +40 -0
- package/skills/trtc-ai-service/auto_adapters/node-backend/fastify.js.tpl +27 -0
- package/skills/trtc-ai-service/auto_adapters/node-backend/koa.js.tpl +31 -0
- package/skills/trtc-ai-service/auto_adapters/node-backend/manifest.yaml +47 -0
- package/skills/trtc-ai-service/auto_adapters/python-backend/README.md +22 -0
- package/skills/trtc-ai-service/auto_adapters/python-backend/django.py.tpl +32 -0
- package/skills/trtc-ai-service/auto_adapters/python-backend/fastapi.py.tpl +35 -0
- package/skills/trtc-ai-service/auto_adapters/python-backend/flask.py.tpl +31 -0
- package/skills/trtc-ai-service/auto_adapters/python-backend/manifest.yaml +45 -0
- package/skills/trtc-ai-service/capabilities/__init__.py +43 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/.env.example +29 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/INTEGRATION.md +134 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/INTERFACE_ADAPT.md +111 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/QUICK_START.md +62 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/manifest.yaml +250 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/requirements.txt +6 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/src/__init__.py +10 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/src/_capability_loader.py +218 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/src/agent.py +231 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/src/credentials.py +132 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/src/health.py +355 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/src/log_filter.py +76 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/src/modality.py +109 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/src/server.py +312 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/src/trtc_client.py +315 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/src/usersig.py +90 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/tests/test_skeleton.py +216 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/web-demo/README.md +48 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/web-demo/app.js +415 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/web-demo/index.html +68 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/web-demo/styles.css +136 -0
- package/skills/trtc-ai-service/capabilities/digital-human/README.md +31 -0
- package/skills/trtc-ai-service/capabilities/digital-human/manifest.yaml +64 -0
- package/skills/trtc-ai-service/capabilities/digital-human/src/__init__.py +2 -0
- package/skills/trtc-ai-service/capabilities/digital-human/src/router.py +43 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/INTERFACE_ADAPT.md +353 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/README.md +44 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/manifest.yaml +227 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/__init__.py +2 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/adapters/__init__.py +9 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/adapters/default_rest.py +242 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/adapters/factory.py +89 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/adapters/local_queue.py +258 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/adapters/mock.py +132 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/core/__init__.py +25 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/core/intent_detector.py +75 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/core/models.py +163 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/core/service.py +192 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/feedback_store.py +54 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/ports/__init__.py +4 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/ports/handoff_client.py +86 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/queue.py +62 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/router.py +201 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/summary_link.py +77 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/trigger.py +25 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/INTERFACE_ADAPT.md +297 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/README.md +51 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/data/faq.json +20 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/manifest.yaml +211 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/__init__.py +8 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/adapters/__init__.py +9 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/adapters/default_rest.py +209 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/adapters/factory.py +86 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/adapters/local_json.py +172 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/adapters/mock.py +91 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/core/__init__.py +12 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/core/models.py +77 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/core/scoring.py +73 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/core/service.py +78 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/ports/__init__.py +4 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/ports/kb_client.py +61 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/retriever.py +56 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/router.py +85 -0
- package/skills/trtc-ai-service/capabilities/session-summary/INTERFACE_ADAPT.md +99 -0
- package/skills/trtc-ai-service/capabilities/session-summary/README.md +47 -0
- package/skills/trtc-ai-service/capabilities/session-summary/data/test_session.json +18 -0
- package/skills/trtc-ai-service/capabilities/session-summary/manifest.yaml +165 -0
- package/skills/trtc-ai-service/capabilities/session-summary/src/__init__.py +2 -0
- package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/__init__.py +5 -0
- package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/base.py +31 -0
- package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/default_rest.py +67 -0
- package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/factory.py +51 -0
- package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/local_json.py +42 -0
- package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/mock.py +22 -0
- package/skills/trtc-ai-service/capabilities/session-summary/src/recorder.py +210 -0
- package/skills/trtc-ai-service/capabilities/session-summary/src/router.py +93 -0
- package/skills/trtc-ai-service/capabilities/session-summary/src/summarizer.py +163 -0
- package/skills/trtc-ai-service/capabilities/tool-calling/INTERFACE_ADAPT.md +158 -0
- package/skills/trtc-ai-service/capabilities/tool-calling/README.md +50 -0
- package/skills/trtc-ai-service/capabilities/tool-calling/data/tools.yaml +58 -0
- package/skills/trtc-ai-service/capabilities/tool-calling/examples/__init__.py +1 -0
- package/skills/trtc-ai-service/capabilities/tool-calling/examples/local_tools.py +101 -0
- package/skills/trtc-ai-service/capabilities/tool-calling/manifest.yaml +146 -0
- package/skills/trtc-ai-service/capabilities/tool-calling/src/__init__.py +8 -0
- package/skills/trtc-ai-service/capabilities/tool-calling/src/dispatcher.py +54 -0
- package/skills/trtc-ai-service/capabilities/tool-calling/src/registry.py +219 -0
- package/skills/trtc-ai-service/capabilities/tool-calling/src/router.py +50 -0
- package/skills/trtc-ai-service/references/business-contract-spec.md +263 -0
- package/skills/trtc-ai-service/scenarios/custom-builder/README.md +86 -0
- package/skills/trtc-ai-service/scenarios/custom-builder/output-templates/recipe.yaml.j2 +194 -0
- package/skills/trtc-ai-service/scenarios/custom-builder/prompts/q1-business-scenario.md +43 -0
- package/skills/trtc-ai-service/scenarios/custom-builder/prompts/q2-io-modality.md +57 -0
- package/skills/trtc-ai-service/scenarios/custom-builder/prompts/q3-ui-form.md +55 -0
- package/skills/trtc-ai-service/scenarios/custom-builder/prompts/q4-capabilities.md +78 -0
- package/skills/trtc-ai-service/scenarios/customer-service/README.md +114 -0
- package/skills/trtc-ai-service/scenarios/customer-service/recipe.yaml +154 -0
- package/skills/trtc-ai-service/scenarios/customer-service/sample-data/README.md +32 -0
- package/skills/trtc-ai-service/scenarios/customer-service/sample-data/faq-sample.json +37 -0
- package/skills/trtc-ai-service/scenarios/customer-service/system-prompt.template.md +94 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/admin-board/app.js +347 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/admin-board/index.html +125 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/admin-board/styles.css +487 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/admin-board/tokens.css +71 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/design-system/DESIGN_GUIDELINES.md +370 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/README.md +68 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/app.js +1307 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/data.js +40 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/index.html +233 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/mock-shop.json +21 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/styles.css +603 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/tokens.css +71 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/widget-floating/agent-link.js +323 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/widget-floating/app.js +458 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/widget-floating/index.html +109 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/widget-floating/styles.css +489 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/widget-floating/tokens.css +59 -0
- package/skills/trtc-ai-service/scripts/add-capability.py +364 -0
- package/skills/trtc-ai-service/scripts/contract-adapt.py +334 -0
- package/skills/trtc-ai-service/scripts/detect-stack.py +40 -0
- package/skills/trtc-ai-service/scripts/lib/__init__.py +20 -0
- package/skills/trtc-ai-service/scripts/lib/adapter_codegen.py +509 -0
- package/skills/trtc-ai-service/scripts/lib/arbitrator.py +152 -0
- package/skills/trtc-ai-service/scripts/lib/contract_resolver.py +519 -0
- package/skills/trtc-ai-service/scripts/lib/credential_validators.py +253 -0
- package/skills/trtc-ai-service/scripts/lib/curl_parser.py +303 -0
- package/skills/trtc-ai-service/scripts/lib/degrader.py +140 -0
- package/skills/trtc-ai-service/scripts/lib/injector.py +347 -0
- package/skills/trtc-ai-service/scripts/lib/manifest_resolver.py +288 -0
- package/skills/trtc-ai-service/scripts/lib/openapi_parser.py +289 -0
- package/skills/trtc-ai-service/scripts/lib/stack_detector.py +159 -0
- package/skills/trtc-ai-service/scripts/lib/tokens_compile.py +204 -0
- package/skills/trtc-ai-service/scripts/post-install-patch.py +225 -0
- package/skills/trtc-ai-service/scripts/setup-credentials.py +393 -0
- package/skills/trtc-ai-service/scripts/verify-credentials.py +108 -0
- package/skills/trtc-ai-service/start.sh +111 -0
- package/skills/trtc-ai-service/tests/__init__.py +1 -0
- package/skills/trtc-ai-service/tests/test_arbitrator.py +64 -0
- package/skills/trtc-ai-service/tests/test_capability_overlay.py +85 -0
- package/skills/trtc-ai-service/tests/test_contract_resolver.py +190 -0
- package/skills/trtc-ai-service/tests/test_handoff_ports.py +195 -0
- package/skills/trtc-ai-service/tests/test_kb_ports.py +195 -0
- package/skills/trtc-ai-service/tests/test_manifest_resolver.py +95 -0
- package/skills/trtc-ai-service/tests/test_recipe_assembly.py +175 -0
- package/skills/trtc-ai-service/tests/test_stack_and_degrader.py +101 -0
- package/skills/trtc-ai-service/tests/test_verify_credentials.py +285 -0
- package/skills/trtc-ai-service/triggers.yaml +29 -0
- package/skills/trtc-conference/SKILL.md +324 -0
- package/skills/trtc-conference/flows/onboarding.md +205 -0
- package/skills/trtc-conference/flows/topic.md +474 -0
- package/skills/trtc-conference/flows/troubleshoot.md +85 -0
- package/skills/trtc-conference/hooks/pretooluse_require_business_decisions.py +213 -0
- package/skills/trtc-conference/playbooks/medical-quickstart.md +84 -0
- package/skills/trtc-conference/playbooks/official-roomkit.md +97 -0
- package/skills/trtc-conference/references/local-usersig/basic-info-config.ts +39 -0
- package/skills/trtc-conference/references/usersig-handling.md +134 -0
- package/skills/trtc-conference/templates/medical-consultation/src/config/lib-generate-test-usersig-es.min.d.ts +4 -0
- package/skills/trtc-conference/templates/medical-consultation/src/config/lib-generate-test-usersig-es.min.js +2 -0
- package/skills/trtc-conference/tests/__pycache__/test_conference_onboarding_contract.cpython-313-pytest-9.0.2.pyc +0 -0
- package/skills/trtc-conference/tests/__pycache__/test_conference_topic_flow_contract.cpython-313-pytest-9.0.2.pyc +0 -0
- package/skills/trtc-conference/tests/test_conference_index_contract.py +43 -0
- package/skills/trtc-conference/tests/test_conference_onboarding_contract.py +103 -0
- package/skills/trtc-conference/tests/test_conference_template_contract.py +25 -0
- package/skills/trtc-conference/tests/test_conference_topic_flow_contract.py +132 -0
- package/skills/trtc-conference/tools/apply_checks.py +328 -0
- package/skills/trtc-conference/verify_lib/__init__.py +0 -0
- package/skills/{trtc-apply/guardrails/apply_lib → trtc-conference/verify_lib}/rule_parser.py +1 -1
- package/skills/trtc-docs/SKILL.md +91 -119
- package/.cursor/rules/ui-mode.mdc +0 -99
- package/ai-instructions/base.md +0 -13
- package/ai-instructions/ui-mode.md +0 -93
- package/knowledge-base/index.yaml +0 -462
- package/skills/trtc/room-builder/SKILL.md +0 -133
- package/skills/trtc/room-builder/templates/scenarios/medical-consultation/README.md +0 -108
- package/skills/trtc/room-builder/tools/render_ai_instructions.py +0 -226
- package/skills/trtc-apply/SKILL.md +0 -97
- package/skills/trtc-onboarding/SKILL.md +0 -841
- package/skills/trtc-onboarding/reference/path-a1-demo.md +0 -103
- package/skills/trtc-onboarding/reference/path-a2-integrate.md +0 -737
- package/skills/trtc-onboarding/reference/path-b-troubleshoot.md +0 -186
- package/skills/trtc-onboarding/reference/path-c-expand.md +0 -43
- package/skills/trtc-onboarding/reference/supported-matrix.md +0 -100
- package/skills/trtc-search/SKILL.md +0 -228
- package/skills/trtc-topic/SKILL.md +0 -622
- package/skills/trtc-topic/scripts/apply.py +0 -581
- package/skills/trtc-topic/scripts/lib/state_machine.py +0 -328
- package/skills/trtc-topic/tests/README.md +0 -70
- package/skills/trtc-topic/tests/conftest.py +0 -72
- package/skills/trtc-topic/tests/test_apply_cli.py +0 -480
- package/skills/trtc-topic/tests/test_end_to_end.py +0 -305
- package/skills/trtc-topic/tests/test_finalize_session.py +0 -51
- package/skills/trtc-topic/tests/test_gates.py +0 -316
- package/skills/trtc-topic/tests/test_session_resolver.py +0 -260
- package/skills/trtc-topic/tests/test_state_machine.py +0 -414
- package/skills/trtc-topic/tests/test_stop_require_apply.py +0 -99
- package/skills/trtc-topic/tests/test_topic_skill_invariants.py +0 -130
- /package/skills/{trtc-topic → trtc}/runtime/lib/platforms.py +0 -0
- /package/skills/{trtc-topic → trtc}/runtime/telemetry_collector.py +0 -0
- /package/skills/{trtc-onboarding/reference → trtc/runtime}/usersig-handling.md +0 -0
- /package/skills/{trtc-topic/scripts → trtc/tools}/finalize_session.py +0 -0
- /package/skills/{trtc-apply/guardrails/apply_lib → trtc-ai-service/capabilities/conversation-core/tests}/__init__.py +0 -0
- /package/skills/{trtc-topic → trtc-conference}/references/execution-units.yaml +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios/medical-consultation/src/config → trtc-conference/references/local-usersig}/lib-generate-test-usersig-es.min.d.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios/medical-consultation/src/config → trtc-conference/references/local-usersig}/lib-generate-test-usersig-es.min.js +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/docs/backend-contract.zh-CN.md +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/docs/integration.zh-CN.md +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/docs/theme.zh-CN.md +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/index.html +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/package.json +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/postcss.config.js +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/App.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/ConsultationManagePanel.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/LanguageSwitch.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/LoadingSpinner.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalAlert.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalBusinessPanel.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalButton.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalConfirmDialog.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalDataPanel.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalRecordPanel.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/PrescriptionPanel.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/config/basic-info-config.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/config/runtime-config.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/env.d.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/ConsultationChatPanel.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/ConsultationMembersPanel.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/ConsultationTranscriptionPanel.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/ConsultationVideoStage.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/InviteDoctorDialog.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/KickMemberConfirmDialog.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/types.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/useConsultationChat.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/useConsultationDevices.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/useConsultationParticipants.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/useConsultationPermissions.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/utils.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/i18n/en-US/index.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/i18n/index.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/i18n/medicalTranslate.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/i18n/state.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/i18n/zh-CN/index.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/main.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/mock/appointments.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/mock/users.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/router/index.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/index.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/integration/appointmentService.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/integration/authService.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/integration/launchContext.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/integration/userService.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/mock/appointmentService.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/mock/authService.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/mock/userService.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/types.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/shared/icons.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/styles/index.css +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/styles/tailwind.css +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/styles/theme.css +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/utils/auth.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/utils/format.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/utils/navigation.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/utils/session.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/DoctorConsultationView.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/DoctorDashboardView.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/LoginView.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/PatientConsultationFinishedView.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/PatientConsultationView.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/PatientSelectDoctorView.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/PatientWaitingView.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/tsconfig.json +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/tsconfig.node.json +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/vite.config.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation//346/216/245/345/205/245/350/257/264/346/230/216.md" +0 -0
- /package/skills/{trtc-topic/runtime/lib → trtc-conference/tools}/__init__.py +0 -0
|
@@ -1,216 +1,1085 @@
|
|
|
1
1
|
# 平台 Slice 模板
|
|
2
2
|
|
|
3
3
|
> **本文件是平台实现 slice 的标准模板。**
|
|
4
|
-
> 复制本文件到 `slices/{product}/{platform}/{ability}.md
|
|
4
|
+
> 复制本文件到 `slices/{product}/{platform}/{ability}.md`,按 `<!-- 指引: ... -->` 批注填写内容,**填完后删除所有批注**。
|
|
5
5
|
>
|
|
6
|
-
>
|
|
6
|
+
> **三步走**:
|
|
7
|
+
> 1. 复制本文件 → 把 `{占位符}` 全部替换为真实内容
|
|
8
|
+
> 2. 对照每个 section 批注里的 ✅ 正例 / ❌ 反例自查
|
|
9
|
+
> 3. 跑批注里给出的「验证命令」,通过后再提交
|
|
10
|
+
> 复制本文件到 `slices/{product}/{platform}/{ability}.md`,按 `<!-- 指引: ... -->` 批注填写内容,**填完后删除所有批注**。
|
|
11
|
+
>
|
|
12
|
+
> **三步走**:
|
|
13
|
+
> 1. 复制本文件 → 把 `{占位符}` 全部替换为真实内容
|
|
14
|
+
> 2. 对照每个 section 批注里的 ✅ 正例 / ❌ 反例自查
|
|
15
|
+
> 3. 跑批注里给出的「验证命令」,通过后再提交
|
|
16
|
+
>
|
|
17
|
+
> **填写范例**:请参考 [`slices/live/ios/coguest-apply.md`](slices/live/ios/coguest-apply.md) — 目前最完整的平台 slice,包含所有 section 的真实内容。
|
|
18
|
+
> **完整规范**:见 [`slice-spec.md`](slice-spec.md) — 仅在批注不够用时回查。
|
|
19
|
+
> **填写范例**:请参考 [`slices/live/ios/coguest-apply.md`](slices/live/ios/coguest-apply.md) — 目前最完整的平台 slice,包含所有 section 的真实内容。
|
|
20
|
+
> **完整规范**:见 [`slice-spec.md`](slice-spec.md) — 仅在批注不够用时回查。
|
|
7
21
|
|
|
8
22
|
---
|
|
9
23
|
|
|
10
24
|
```yaml
|
|
11
25
|
---
|
|
12
|
-
id: {product}/{ability} # [必填]
|
|
26
|
+
id: {product}/{ability} # [必填] 与对应的 per-product platform index 中的 id 一致
|
|
13
27
|
platform: {platform} # [必填] ios / android / web / flutter / electron
|
|
14
|
-
api_docs:
|
|
28
|
+
api_docs: # [必填] 该平台对应的 API 参考文档链接,至少 1 条
|
|
29
|
+
api_docs: # [必填] 该平台对应的 API 参考文档链接,至少 1 条
|
|
15
30
|
- title: {API 类名/模块名}
|
|
16
31
|
url: https://...
|
|
17
32
|
---
|
|
18
33
|
```
|
|
19
34
|
|
|
20
35
|
<!-- 指引: Frontmatter 字段说明:
|
|
21
|
-
- id:
|
|
36
|
+
- id: 与对应的 per-product platform index 中的 slice id 完全一致
|
|
22
37
|
- platform: 当前平台标识
|
|
23
38
|
- api_docs: 该功能在该平台的 API 参考文档链接(接口签名、参数类型、返回值等)。
|
|
24
39
|
产品级概览已不再放文档链接,教程/指南类 URL 也不放在 api_docs 里。
|
|
25
40
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
41
|
+
1️⃣ 你必须写什么
|
|
42
|
+
- id:与 index.yaml 中的 slice id **完全一致**(含连字符大小写)
|
|
43
|
+
- platform:当前平台标识(只能是 ios / android / web / flutter / electron 之一)
|
|
44
|
+
- api_docs:该功能在该平台的 API 参考文档链接(精确到类/模块,至少 1 条)
|
|
45
|
+
|
|
46
|
+
2️⃣ 写作模板
|
|
47
|
+
api_docs:
|
|
48
|
+
- title: {本 slice 涉及的具体类名,如 CoGuestStore}
|
|
49
|
+
url: https://{平台 SDK 文档站}/.../{类名小写}/
|
|
50
|
+
|
|
51
|
+
判定 url 是否合格:打开链接,**第一屏**就能看到本 slice 涉及的**具体类的方法签名**(参数名、参数类型、返回值)→ ✅ 合格
|
|
52
|
+
|
|
53
|
+
3️⃣ ✅ 正例(摘自 live/ios/coguest-apply)
|
|
54
|
+
api_docs:
|
|
55
|
+
- title: CoGuestStore
|
|
56
|
+
url: https://tencent-rtc.github.io/TUIKit_iOS/documentation/atomicxcore/cogueststore/
|
|
57
|
+
- title: DeviceStore
|
|
58
|
+
url: https://tencent-rtc.github.io/TUIKit_iOS/documentation/atomicxcore/devicestore/
|
|
59
|
+
为什么是正例:
|
|
60
|
+
- 链接路径含 /documentation/ → 是 API 参考站
|
|
61
|
+
- 路径末尾是具体类名 cogueststore → 精确到类
|
|
62
|
+
- slice 涉及两个 Store → 分别列出,不省略
|
|
63
|
+
|
|
64
|
+
4️⃣ ❌ 反例
|
|
65
|
+
- title: TRTC iOS SDK
|
|
66
|
+
url: https://trtc.io/sdk ← SDK 首页:AI 拿不到类签名,生成不存在的 API
|
|
67
|
+
- title: 连麦集成指南
|
|
68
|
+
url: https://trtc.io/zh/document/74598 ← 教程页:API 名常被简化,AI 引用错误
|
|
69
|
+
- title: TODO
|
|
70
|
+
url: TODO ← 占位:永远不会被替换,半年后就是废 slice
|
|
71
|
+
|
|
72
|
+
5️⃣ 必填项语义三件套
|
|
73
|
+
- 违反后果:链接非类级 → AI 生成不存在的 API 名 → 客户编译报错投诉
|
|
74
|
+
- 验证手段:python scripts/validate_api_docs.py {file}
|
|
75
|
+
通过标准:每条 url 返回 200;url 含 /documentation/ 或 /api/;打开链接的页面 H1 必须包含 frontmatter 里的 title
|
|
76
|
+
- 绕过条件:该平台官方确实无 API 参考站(如某些早期 Electron 模块)→ 必须填头文件 GitHub 永久链接(含 commit hash),且在 PR 中说明
|
|
30
77
|
|
|
31
|
-
|
|
78
|
+
注:name / tags / platforms / related 在产品级概览中维护,此处不重复。
|
|
32
79
|
-->
|
|
33
80
|
|
|
34
81
|
# {名称} — {平台} 实现
|
|
35
82
|
|
|
36
83
|
## 前置条件 [必填]
|
|
37
84
|
|
|
38
|
-
<!-- 指引:
|
|
39
|
-
本 section 只写两类内容:
|
|
85
|
+
<!-- 指引: 前置条件 [必填]
|
|
40
86
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
87
|
+
1️⃣ 你必须写什么
|
|
88
|
+
列出本 slice 代码运行前必须满足的状态,**用引用形式**指向其他 slice。
|
|
89
|
+
通用依赖(SDK 安装、基础权限)已在 login-auth 中统一描述,**禁止重复**。
|
|
44
90
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
91
|
+
本 section 只写两类内容:
|
|
92
|
+
- 增量依赖 — 本 slice 额外需要的库/权限(如美颜 SDK、蓝牙权限)
|
|
93
|
+
- 前置状态 — 本功能依赖哪些 Store 已初始化/操作已完成,引用对应 slice ID
|
|
94
|
+
|
|
95
|
+
2️⃣ 写作模板
|
|
96
|
+
**通用依赖**:见 [login-auth 平台 slice](../login-auth.md)
|
|
97
|
+
|
|
98
|
+
**额外依赖**:{无 / 列出本 slice 独有依赖}
|
|
99
|
+
|
|
100
|
+
**前置状态**:
|
|
101
|
+
- `{Store/状态}.{属性} == {期望值}`(→ {产品}/{依赖 slice})
|
|
102
|
+
- {跨角色前置:如"主播端已开播"}
|
|
103
|
+
|
|
104
|
+
3️⃣ ✅ 正例(摘自 live/ios/coguest-apply)
|
|
105
|
+
**通用依赖**:见 [login-auth 平台 slice](../login-auth.md)
|
|
106
|
+
|
|
107
|
+
**额外依赖**:无
|
|
49
108
|
|
|
50
|
-
|
|
109
|
+
**前置状态**:
|
|
110
|
+
- 已完成登录(→ live/login-auth),`LoginStore.shared.isLogin == true`
|
|
111
|
+
- 已加入房间且角色为观众(→ live/room-lifecycle),`RoomStore.shared.localUser.role == .audience`
|
|
112
|
+
- 主播端已开播且开启了"接受连麦申请"开关
|
|
113
|
+
为什么是正例:
|
|
114
|
+
- 用 → slice-id 标注依赖,不重复说明怎么登录
|
|
115
|
+
- 给出可机械验证的状态条件(role == .audience)
|
|
116
|
+
- 包含跨角色前置(主播端配置)
|
|
51
117
|
|
|
52
|
-
|
|
53
|
-
|
|
118
|
+
4️⃣ ❌ 反例
|
|
119
|
+
要先安装 SDK 包 `pod 'TUIKit'`,然后调用 LoginStore.login(userId:userSig:) 登录,
|
|
120
|
+
然后调用 RoomStore.joinRoom(roomId:) 加入房间,...
|
|
121
|
+
为什么是反例:
|
|
122
|
+
- 重复了 base-setup / login-auth 的内容
|
|
123
|
+
- 这些内容会随版本变化,这里写一份等于埋雷
|
|
124
|
+
- 没用引用形式,信息易漂移
|
|
125
|
+
→ 改为 → live/login-auth 引用
|
|
54
126
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
127
|
+
5️⃣ 必填项语义三件套
|
|
128
|
+
- 违反后果:重复其他 slice 内容 → 信息漂移(版本升级后这里没同步)→ AI 生成过时代码
|
|
129
|
+
- 验证手段:全文搜安装关键字应命中 0 次:
|
|
130
|
+
grep -E "pod install|pod 'AtomicXCore'|npm install|implementation 'com.tencent" {file}
|
|
131
|
+
- 绕过条件:本 slice 确实需要额外依赖(如美颜 SDK)→ 在「额外依赖」段列出
|
|
132
|
+
<!-- 指引: 前置条件 [必填]
|
|
133
|
+
|
|
134
|
+
1️⃣ 你必须写什么
|
|
135
|
+
列出本 slice 代码运行前必须满足的状态,**用引用形式**指向其他 slice。
|
|
136
|
+
通用依赖(SDK 安装、基础权限)已在 login-auth 中统一描述,**禁止重复**。
|
|
137
|
+
|
|
138
|
+
本 section 只写两类内容:
|
|
139
|
+
- 增量依赖 — 本 slice 额外需要的库/权限(如美颜 SDK、蓝牙权限)
|
|
140
|
+
- 前置状态 — 本功能依赖哪些 Store 已初始化/操作已完成,引用对应 slice ID
|
|
141
|
+
|
|
142
|
+
2️⃣ 写作模板
|
|
143
|
+
**通用依赖**:见 [login-auth 平台 slice](../login-auth.md)
|
|
144
|
+
|
|
145
|
+
**额外依赖**:{无 / 列出本 slice 独有依赖}
|
|
146
|
+
|
|
147
|
+
**前置状态**:
|
|
148
|
+
- `{Store/状态}.{属性} == {期望值}`(→ {产品}/{依赖 slice})
|
|
149
|
+
- {跨角色前置:如"主播端已开播"}
|
|
150
|
+
|
|
151
|
+
3️⃣ ✅ 正例(摘自 live/ios/coguest-apply)
|
|
152
|
+
**通用依赖**:见 [login-auth 平台 slice](../login-auth.md)
|
|
153
|
+
|
|
154
|
+
**额外依赖**:无
|
|
155
|
+
|
|
156
|
+
**前置状态**:
|
|
157
|
+
- 已完成登录(→ live/login-auth),`LoginStore.shared.isLogin == true`
|
|
158
|
+
- 已加入房间且角色为观众(→ live/room-lifecycle),`RoomStore.shared.localUser.role == .audience`
|
|
159
|
+
- 主播端已开播且开启了"接受连麦申请"开关
|
|
160
|
+
为什么是正例:
|
|
161
|
+
- 用 → slice-id 标注依赖,不重复说明怎么登录
|
|
162
|
+
- 给出可机械验证的状态条件(role == .audience)
|
|
163
|
+
- 包含跨角色前置(主播端配置)
|
|
164
|
+
|
|
165
|
+
4️⃣ ❌ 反例
|
|
166
|
+
要先安装 SDK 包 `pod 'TUIKit'`,然后调用 LoginStore.login(userId:userSig:) 登录,
|
|
167
|
+
然后调用 RoomStore.joinRoom(roomId:) 加入房间,...
|
|
168
|
+
为什么是反例:
|
|
169
|
+
- 重复了 base-setup / login-auth 的内容
|
|
170
|
+
- 这些内容会随版本变化,这里写一份等于埋雷
|
|
171
|
+
- 没用引用形式,信息易漂移
|
|
172
|
+
→ 改为 → live/login-auth 引用
|
|
173
|
+
|
|
174
|
+
5️⃣ 必填项语义三件套
|
|
175
|
+
- 违反后果:重复其他 slice 内容 → 信息漂移(版本升级后这里没同步)→ AI 生成过时代码
|
|
176
|
+
- 验证手段:全文搜安装关键字应命中 0 次:
|
|
177
|
+
grep -E "pod install|pod 'AtomicXCore'|npm install|implementation 'com.tencent" {file}
|
|
178
|
+
- 绕过条件:本 slice 确实需要额外依赖(如美颜 SDK)→ 在「额外依赖」段列出
|
|
59
179
|
-->
|
|
60
180
|
|
|
181
|
+
**通用依赖**:见 [login-auth 平台 slice](../login-auth.md)
|
|
182
|
+
**通用依赖**:见 [login-auth 平台 slice](../login-auth.md)
|
|
183
|
+
|
|
184
|
+
**额外依赖**:
|
|
185
|
+
<!-- 如有本 slice 独有依赖,在此列出;没有则写「无」 -->
|
|
186
|
+
**额外依赖**:
|
|
187
|
+
<!-- 如有本 slice 独有依赖,在此列出;没有则写「无」 -->
|
|
188
|
+
|
|
189
|
+
**前置状态**:
|
|
190
|
+
<!-- 列出必须满足的前置条件,引用 slice ID -->
|
|
191
|
+
**前置状态**:
|
|
192
|
+
<!-- 列出必须满足的前置条件,引用 slice ID -->
|
|
193
|
+
|
|
61
194
|
## 代码示例 [必填]
|
|
62
195
|
|
|
63
|
-
<!-- 指引:
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
196
|
+
<!-- 指引: 代码示例 [必填]
|
|
197
|
+
|
|
198
|
+
1️⃣ 你必须写什么
|
|
199
|
+
能让 AI 直接学习并产出**可编译、可运行**的代码块。
|
|
200
|
+
代码示例 = 这份 slice 给 AI 的"训练数据",每个细节都会被复制放大。
|
|
201
|
+
|
|
202
|
+
定位是「零件」— 单个功能的完整实现。多个零件如何组装成完整场景,由 scenario 的平台实现文件负责。
|
|
203
|
+
<!-- 指引: 代码示例 [必填]
|
|
204
|
+
|
|
205
|
+
1️⃣ 你必须写什么
|
|
206
|
+
能让 AI 直接学习并产出**可编译、可运行**的代码块。
|
|
207
|
+
代码示例 = 这份 slice 给 AI 的"训练数据",每个细节都会被复制放大。
|
|
208
|
+
|
|
209
|
+
定位是「零件」— 单个功能的完整实现。多个零件如何组装成完整场景,由 scenario 的平台实现文件负责。
|
|
210
|
+
|
|
211
|
+
2️⃣ 6 条最低标准(必须全部满足)
|
|
212
|
+
|
|
213
|
+
| 维度 | 最低标准 |
|
|
214
|
+
|------|---------|
|
|
215
|
+
| 可编译 | 含完整 import、完整类/函数闭包,**严禁** ... 省略任何逻辑分支 |
|
|
216
|
+
| 可运行 | 补充业务参数后可直接跑通;业务参数用 {TODO: 填入 xxx} 占位 |
|
|
217
|
+
| 有日志锚点 | 关键路径必须有 print/console.log/Log.d,带模块前缀如 [CoGuest] |
|
|
218
|
+
| 有错误处理 | 每个 .failure / catch / error 分支必须有面向用户的处理(UI 可见的 errorMessage / alert),不允许只 print |
|
|
219
|
+
| 多角色分开写 | 主播端 / 观众端必须拆成独立代码块,不耦合 |
|
|
220
|
+
| 可组合性 | 前置依赖通过注释声明 // 前置:登录完成(→ live/login-auth),不硬编码其他 slice 调用 |
|
|
221
|
+
|
|
222
|
+
组织方式:按用户操作流程,用 MARK / region / 注释分隔各步骤(初始化 → 核心操作 → 事件监听 → 错误处理 → 清理)
|
|
223
|
+
|
|
224
|
+
3️⃣ ✅ 正例(摘自 live/ios/coguest-apply)
|
|
225
|
+
```swift
|
|
226
|
+
// 前置:登录完成(→ chat/login-auth)
|
|
227
|
+
// 前置:已加入房间(→ live/room-lifecycle)
|
|
228
|
+
|
|
229
|
+
import TencentImSDKPlugin
|
|
230
|
+
import Combine
|
|
231
|
+
|
|
232
|
+
class CoGuestApplyViewModel: ObservableObject {
|
|
233
|
+
@Published var errorMessage: String? // ← UI 必需,展示给用户
|
|
234
|
+
private var cancellables = Set<AnyCancellable>()
|
|
235
|
+
|
|
236
|
+
func applyForSeat() {
|
|
237
|
+
print("[CoGuest] 开始发起连麦申请") // ← 日志锚点
|
|
238
|
+
|
|
239
|
+
CoGuestStore.shared.applyForSeat(timeout: 30)
|
|
240
|
+
.sink { [weak self] completion in // ← [weak self] 必需
|
|
241
|
+
if case .failure(let error) = completion {
|
|
242
|
+
print("[CoGuest] 申请失败: \(error)")
|
|
243
|
+
self?.errorMessage = "连麦申请失败,请重试" // ← 用户可见
|
|
244
|
+
}
|
|
245
|
+
} receiveValue: { [weak self] _ in
|
|
246
|
+
print("[CoGuest] 申请已发送")
|
|
247
|
+
self?.errorMessage = nil
|
|
248
|
+
}
|
|
249
|
+
.store(in: &cancellables)
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
为什么是正例:
|
|
254
|
+
- 顶部 // 前置 注释声明依赖 slice,不耦合调用
|
|
255
|
+
- import 完整,可直接编译
|
|
256
|
+
- 业务参数(timeout)用真实值不是 xxx
|
|
257
|
+
- 关键路径有 print 锚点,带 [CoGuest] 模块前缀
|
|
258
|
+
- 每个 failure 分支都设置 errorMessage(UI 可见),不是只 print
|
|
259
|
+
- [weak self] 防循环引用
|
|
260
|
+
|
|
261
|
+
4️⃣ ❌ 反例
|
|
262
|
+
反例 1:用 ... 省略
|
|
263
|
+
func applyForSeat() {
|
|
264
|
+
CoGuestStore.shared.applyForSeat(...) { result in
|
|
265
|
+
// 处理结果
|
|
266
|
+
...
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
→ "..." 跳过了失败处理,AI 学到这个模式后到处省略
|
|
270
|
+
|
|
271
|
+
反例 2:仅 print 错误
|
|
272
|
+
.sink { completion in
|
|
273
|
+
if case .failure(let error) = completion {
|
|
274
|
+
print("error: \(error)") // ← 用户看不到!
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
→ 客户线上故障时用户只看到无反应
|
|
278
|
+
|
|
279
|
+
反例 3:省略 import
|
|
280
|
+
class XXX {
|
|
281
|
+
var cancellables = Set<AnyCancellable>()
|
|
282
|
+
// ↑ 没 import Combine,代码贴出来不能编译
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
反例 4:业务参数瞎编
|
|
286
|
+
applyForSeat(seatIndex: 1, timeout: 60, reason: "我想连麦")
|
|
287
|
+
→ "我想连麦" 应该用 {TODO: 填入业务申请理由} 占位
|
|
288
|
+
|
|
289
|
+
反例 5:多角色塞一个类里
|
|
290
|
+
class CoGuestManager {
|
|
291
|
+
func audienceApply() { ... }
|
|
292
|
+
func hostApprove() { ... }
|
|
293
|
+
}
|
|
294
|
+
→ 主播观众职责混合,AI 生成时随机抽方法
|
|
295
|
+
|
|
296
|
+
5️⃣ 必填项语义三件套
|
|
297
|
+
- 违反后果:含 ... / 仅 print 错误 / 省略 import → AI 学坏 → 跨 slice 蔓延错误模式 → slice 不可合并,**已合并的批量回退**(2025-03 真实事故,2 周返工)
|
|
298
|
+
- 验证手段:
|
|
299
|
+
# 1. 抽取代码块编译
|
|
300
|
+
python scripts/extract_code.py {file} | xcodebuild build ...
|
|
301
|
+
# 2. 静态扫描
|
|
302
|
+
grep -E "\\.\\.\\.|//\\s*处理结果|//\\s*TODO[^:]" {file} # 必须命中 0 次
|
|
303
|
+
grep -E "errorMessage|alert|toast" {file} # 每个 .failure 块至少 1 处
|
|
304
|
+
- 绕过条件:无。"先占位以后补"的代码示例 = 永远不会补的代码示例
|
|
305
|
+
2️⃣ 6 条最低标准(必须全部满足)
|
|
306
|
+
|
|
307
|
+
| 维度 | 最低标准 |
|
|
308
|
+
|------|---------|
|
|
309
|
+
| 可编译 | 含完整 import、完整类/函数闭包,**严禁** ... 省略任何逻辑分支 |
|
|
310
|
+
| 可运行 | 补充业务参数后可直接跑通;业务参数用 {TODO: 填入 xxx} 占位 |
|
|
311
|
+
| 有日志锚点 | 关键路径必须有 print/console.log/Log.d,带模块前缀如 [CoGuest] |
|
|
312
|
+
| 有错误处理 | 每个 .failure / catch / error 分支必须有面向用户的处理(UI 可见的 errorMessage / alert),不允许只 print |
|
|
313
|
+
| 多角色分开写 | 主播端 / 观众端必须拆成独立代码块,不耦合 |
|
|
314
|
+
| 可组合性 | 前置依赖通过注释声明 // 前置:登录完成(→ live/login-auth),不硬编码其他 slice 调用 |
|
|
315
|
+
|
|
316
|
+
组织方式:按用户操作流程,用 MARK / region / 注释分隔各步骤(初始化 → 核心操作 → 事件监听 → 错误处理 → 清理)
|
|
317
|
+
|
|
318
|
+
3️⃣ ✅ 正例(摘自 live/ios/coguest-apply)
|
|
319
|
+
```swift
|
|
320
|
+
// 前置:登录完成(→ chat/login-auth)
|
|
321
|
+
// 前置:已加入房间(→ live/room-lifecycle)
|
|
322
|
+
|
|
323
|
+
import TencentImSDKPlugin
|
|
324
|
+
import Combine
|
|
325
|
+
|
|
326
|
+
class CoGuestApplyViewModel: ObservableObject {
|
|
327
|
+
@Published var errorMessage: String? // ← UI 必需,展示给用户
|
|
328
|
+
private var cancellables = Set<AnyCancellable>()
|
|
329
|
+
|
|
330
|
+
func applyForSeat() {
|
|
331
|
+
print("[CoGuest] 开始发起连麦申请") // ← 日志锚点
|
|
332
|
+
|
|
333
|
+
CoGuestStore.shared.applyForSeat(timeout: 30)
|
|
334
|
+
.sink { [weak self] completion in // ← [weak self] 必需
|
|
335
|
+
if case .failure(let error) = completion {
|
|
336
|
+
print("[CoGuest] 申请失败: \(error)")
|
|
337
|
+
self?.errorMessage = "连麦申请失败,请重试" // ← 用户可见
|
|
338
|
+
}
|
|
339
|
+
} receiveValue: { [weak self] _ in
|
|
340
|
+
print("[CoGuest] 申请已发送")
|
|
341
|
+
self?.errorMessage = nil
|
|
342
|
+
}
|
|
343
|
+
.store(in: &cancellables)
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
```
|
|
347
|
+
为什么是正例:
|
|
348
|
+
- 顶部 // 前置 注释声明依赖 slice,不耦合调用
|
|
349
|
+
- import 完整,可直接编译
|
|
350
|
+
- 业务参数(timeout)用真实值不是 xxx
|
|
351
|
+
- 关键路径有 print 锚点,带 [CoGuest] 模块前缀
|
|
352
|
+
- 每个 failure 分支都设置 errorMessage(UI 可见),不是只 print
|
|
353
|
+
- [weak self] 防循环引用
|
|
354
|
+
|
|
355
|
+
4️⃣ ❌ 反例
|
|
356
|
+
反例 1:用 ... 省略
|
|
357
|
+
func applyForSeat() {
|
|
358
|
+
CoGuestStore.shared.applyForSeat(...) { result in
|
|
359
|
+
// 处理结果
|
|
360
|
+
...
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
→ "..." 跳过了失败处理,AI 学到这个模式后到处省略
|
|
364
|
+
|
|
365
|
+
反例 2:仅 print 错误
|
|
366
|
+
.sink { completion in
|
|
367
|
+
if case .failure(let error) = completion {
|
|
368
|
+
print("error: \(error)") // ← 用户看不到!
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
→ 客户线上故障时用户只看到无反应
|
|
372
|
+
|
|
373
|
+
反例 3:省略 import
|
|
374
|
+
class XXX {
|
|
375
|
+
var cancellables = Set<AnyCancellable>()
|
|
376
|
+
// ↑ 没 import Combine,代码贴出来不能编译
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
反例 4:业务参数瞎编
|
|
380
|
+
applyForSeat(seatIndex: 1, timeout: 60, reason: "我想连麦")
|
|
381
|
+
→ "我想连麦" 应该用 {TODO: 填入业务申请理由} 占位
|
|
382
|
+
|
|
383
|
+
反例 5:多角色塞一个类里
|
|
384
|
+
class CoGuestManager {
|
|
385
|
+
func audienceApply() { ... }
|
|
386
|
+
func hostApprove() { ... }
|
|
387
|
+
}
|
|
388
|
+
→ 主播观众职责混合,AI 生成时随机抽方法
|
|
389
|
+
|
|
390
|
+
5️⃣ 必填项语义三件套
|
|
391
|
+
- 违反后果:含 ... / 仅 print 错误 / 省略 import → AI 学坏 → 跨 slice 蔓延错误模式 → slice 不可合并,**已合并的批量回退**(2025-03 真实事故,2 周返工)
|
|
392
|
+
- 验证手段:
|
|
393
|
+
# 1. 抽取代码块编译
|
|
394
|
+
python scripts/extract_code.py {file} | xcodebuild build ...
|
|
395
|
+
# 2. 静态扫描
|
|
396
|
+
grep -E "\\.\\.\\.|//\\s*处理结果|//\\s*TODO[^:]" {file} # 必须命中 0 次
|
|
397
|
+
grep -E "errorMessage|alert|toast" {file} # 每个 .failure 块至少 1 处
|
|
398
|
+
- 绕过条件:无。"先占位以后补"的代码示例 = 永远不会补的代码示例
|
|
82
399
|
-->
|
|
83
400
|
|
|
84
|
-
## 调用时序 [
|
|
401
|
+
## 调用时序 [条件必填:多角色异步交互 或 回调嵌套 ≥3 层]
|
|
402
|
+
## 调用时序 [条件必填:多角色异步交互 或 回调嵌套 ≥3 层]
|
|
85
403
|
|
|
86
|
-
<!-- 指引:
|
|
87
|
-
— 多角色交互(主播/观众/服务端三方时序不容易从单段代码看出)
|
|
88
|
-
— 异步回调链路特别深(3 层以上嵌套回调)
|
|
89
|
-
— 有隐含的时序依赖不写出来容易踩坑(如「必须先订阅再操作」)
|
|
404
|
+
<!-- 指引: 调用时序 [条件必填]
|
|
90
405
|
|
|
91
|
-
|
|
406
|
+
1️⃣ 触发条件(任一满足即必须画)
|
|
407
|
+
- 多角色交互(主播/观众/服务端三方时序不容易从单段代码看出)
|
|
408
|
+
- 异步回调链路特别深(3 层以上嵌套回调)
|
|
409
|
+
- 状态机分支 ≥3 个
|
|
410
|
+
|
|
411
|
+
不满足 → **整段删除**,不要留空。
|
|
412
|
+
|
|
413
|
+
2️⃣ 写作模板(ASCII 时序图)
|
|
414
|
+
```
|
|
415
|
+
{角色 A} {SDK / 中介} {角色 B}
|
|
416
|
+
│ │ │
|
|
417
|
+
├─ {操作} ──→ │ │
|
|
418
|
+
│ ├─ {事件} ──→ │
|
|
419
|
+
│ │ ├─ {响应}
|
|
420
|
+
│ ←─ {回调} ─────┤
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
3️⃣ ✅ 正例(摘自 live/ios/coguest-apply)
|
|
424
|
+
```
|
|
425
|
+
观众端 SDK 主播端
|
|
426
|
+
│ │
|
|
427
|
+
├─ applyForSeat ──→ │
|
|
428
|
+
│ │
|
|
429
|
+
│ ←─ onApplication ─┤
|
|
430
|
+
│ │
|
|
431
|
+
│ ←─ approve ──────┤
|
|
432
|
+
│ │
|
|
433
|
+
├─ {打开摄像头/麦克风} │
|
|
434
|
+
│ │
|
|
435
|
+
```
|
|
436
|
+
为什么是正例:
|
|
437
|
+
- 三列对应三方角色(观众/SDK/主播),清晰
|
|
438
|
+
- 每条箭头标注具体方法名/事件名,可对应到代码
|
|
439
|
+
- 顺序贴近真实业务时序
|
|
440
|
+
|
|
441
|
+
4️⃣ ❌ 反例
|
|
442
|
+
观众发起申请,主播收到后处理,然后通知观众。
|
|
443
|
+
→ 不是图,只是一句散文,无法体现并行/异步
|
|
444
|
+
|
|
445
|
+
或者画图但没标方法名:
|
|
446
|
+
观众 → 服务器 → 主播
|
|
447
|
+
→ 无法对应代码,AI 拿不到信息
|
|
448
|
+
|
|
449
|
+
5️⃣ 必填项语义三件套
|
|
450
|
+
- 违反后果:多角色交互无时序图 → AI 生成代码角色行为错位 → 上线后双方互相听不到
|
|
451
|
+
- 验证手段:人工 review,触发条件命中即必有;时序图覆盖所有角色和关键事件
|
|
452
|
+
- 绕过条件:不满足触发条件 → 可省(整段删除)
|
|
453
|
+
<!-- 指引: 调用时序 [条件必填]
|
|
454
|
+
|
|
455
|
+
1️⃣ 触发条件(任一满足即必须画)
|
|
456
|
+
- 多角色交互(主播/观众/服务端三方时序不容易从单段代码看出)
|
|
457
|
+
- 异步回调链路特别深(3 层以上嵌套回调)
|
|
458
|
+
- 状态机分支 ≥3 个
|
|
459
|
+
|
|
460
|
+
不满足 → **整段删除**,不要留空。
|
|
461
|
+
|
|
462
|
+
2️⃣ 写作模板(ASCII 时序图)
|
|
463
|
+
```
|
|
464
|
+
{角色 A} {SDK / 中介} {角色 B}
|
|
465
|
+
│ │ │
|
|
466
|
+
├─ {操作} ──→ │ │
|
|
467
|
+
│ ├─ {事件} ──→ │
|
|
468
|
+
│ │ ├─ {响应}
|
|
469
|
+
│ ←─ {回调} ─────┤
|
|
470
|
+
```
|
|
92
471
|
|
|
93
|
-
|
|
472
|
+
3️⃣ ✅ 正例(摘自 live/ios/coguest-apply)
|
|
473
|
+
```
|
|
474
|
+
观众端 SDK 主播端
|
|
475
|
+
│ │
|
|
476
|
+
├─ applyForSeat ──→ │
|
|
477
|
+
│ │
|
|
478
|
+
│ ←─ onApplication ─┤
|
|
479
|
+
│ │
|
|
480
|
+
│ ←─ approve ──────┤
|
|
481
|
+
│ │
|
|
482
|
+
├─ {打开摄像头/麦克风} │
|
|
483
|
+
│ │
|
|
484
|
+
```
|
|
485
|
+
为什么是正例:
|
|
486
|
+
- 三列对应三方角色(观众/SDK/主播),清晰
|
|
487
|
+
- 每条箭头标注具体方法名/事件名,可对应到代码
|
|
488
|
+
- 顺序贴近真实业务时序
|
|
489
|
+
|
|
490
|
+
4️⃣ ❌ 反例
|
|
491
|
+
观众发起申请,主播收到后处理,然后通知观众。
|
|
492
|
+
→ 不是图,只是一句散文,无法体现并行/异步
|
|
493
|
+
|
|
494
|
+
或者画图但没标方法名:
|
|
495
|
+
观众 → 服务器 → 主播
|
|
496
|
+
→ 无法对应代码,AI 拿不到信息
|
|
497
|
+
|
|
498
|
+
5️⃣ 必填项语义三件套
|
|
499
|
+
- 违反后果:多角色交互无时序图 → AI 生成代码角色行为错位 → 上线后双方互相听不到
|
|
500
|
+
- 验证手段:人工 review,触发条件命中即必有;时序图覆盖所有角色和关键事件
|
|
501
|
+
- 绕过条件:不满足触发条件 → 可省(整段删除)
|
|
94
502
|
-->
|
|
95
503
|
|
|
96
|
-
## 平台特有注意事项 [
|
|
504
|
+
## 平台特有注意事项 [必填:至少 1 条]
|
|
505
|
+
## 平台特有注意事项 [必填:至少 1 条]
|
|
506
|
+
|
|
507
|
+
<!-- 指引: 平台特有注意事项 [必填,至少 1 条]
|
|
508
|
+
|
|
509
|
+
1️⃣ 你必须写什么
|
|
510
|
+
仅在该平台才会踩的坑。每条标准:**该平台独有 + 不写出来研发会踩**。
|
|
511
|
+
跨平台通用的注意事项 → 上移到产品级概览的 ALWAYS/NEVER。
|
|
512
|
+
|
|
513
|
+
2️⃣ 写作模板
|
|
514
|
+
### {编号}. {一句话标题}
|
|
515
|
+
**现象**:{开发者会遇到什么具体表现}
|
|
516
|
+
**原因**:{为什么会这样,SDK / 平台机制层面}
|
|
517
|
+
**必须做**:{具体动作,可机械执行}
|
|
518
|
+
|
|
519
|
+
3️⃣ ✅ 正例(iOS)
|
|
520
|
+
### 1. AnyCancellable 必须存为实例属性
|
|
521
|
+
**现象**:.sink 闭包永远不触发,日志没有任何输出
|
|
522
|
+
**原因**:局部变量 cancellable 出作用域后被释放,Combine 自动解除订阅
|
|
523
|
+
**必须做**:声明 `private var cancellables = Set<AnyCancellable>()` 实例属性,
|
|
524
|
+
所有 sink 后接 `.store(in: &cancellables)`
|
|
525
|
+
|
|
526
|
+
### 2. sink 闭包必须显式 [weak self]
|
|
527
|
+
**现象**:VC dismiss 后 ViewModel 不释放,Memory Graph 显示循环引用
|
|
528
|
+
**原因**:sink 闭包对 self 强引用,publisher 又被 self 持有
|
|
529
|
+
**必须做**:所有 .sink { } 闭包第一行加 [weak self]
|
|
530
|
+
|
|
531
|
+
### 3. 首次申请麦克风权限的弹窗在异步线程触发会被忽略
|
|
532
|
+
**现象**:点击连麦按钮后,系统不弹权限对话框,SDK 直接返回权限拒绝
|
|
533
|
+
**原因**:iOS 权限弹窗必须在主线程触发,异步线程调用静默失败
|
|
534
|
+
**必须做**:`DispatchQueue.main.async { applyForSeat() }`
|
|
535
|
+
|
|
536
|
+
为什么这些是正例:
|
|
537
|
+
- 每条都是 iOS 独有(Android/Web 无 Combine、无 [weak self]、权限机制不同)
|
|
538
|
+
- 三段式结构(现象/原因/必须做)清晰,新人能快速 get
|
|
539
|
+
- "必须做" 是具体动作,不是"注意一下"
|
|
97
540
|
|
|
98
|
-
|
|
99
|
-
|
|
541
|
+
4️⃣ ❌ 反例
|
|
542
|
+
### 1. 注意内存管理
|
|
543
|
+
内存管理很重要,要避免泄漏。
|
|
544
|
+
→ "注意""很重要" = 软词;"内存管理"跨平台都有 → 不是平台特有
|
|
100
545
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
— 再说原因(为什么会这样)
|
|
546
|
+
### 2. iOS 上需要权限
|
|
547
|
+
iOS 应用要在 Info.plist 声明权限。
|
|
548
|
+
→ 这是基础常识,不写也不会踩;且 base-setup 已覆盖
|
|
105
549
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
- 该平台的内存/线程问题(如 iOS [weak self]、Android 主线程更新 UI)
|
|
110
|
-
- 该平台的权限行为差异(如 iOS 崩溃 vs Android 返回错误码)
|
|
111
|
-
- 该平台特有的错误码或异常行为
|
|
550
|
+
### 3. 异步代码要小心
|
|
551
|
+
处理异步代码时要注意时序问题。
|
|
552
|
+
→ 全是模糊形容词,无具体动作
|
|
112
553
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
554
|
+
5️⃣ 必填项语义三件套
|
|
555
|
+
- 违反后果:平台特有坑没写 → AI 生成代码在该平台报错 / 行为异常 / 内存泄漏
|
|
556
|
+
- 验证手段:每条必须含"必须做:{具体动作}";描述的现象其他平台不会出现;不出现"注意""小心""很重要"等软词
|
|
557
|
+
- 绕过条件:无(每个平台 slice 都至少要有 1 条)
|
|
558
|
+
<!-- 指引: 平台特有注意事项 [必填,至少 1 条]
|
|
117
559
|
|
|
118
|
-
|
|
119
|
-
|
|
560
|
+
1️⃣ 你必须写什么
|
|
561
|
+
仅在该平台才会踩的坑。每条标准:**该平台独有 + 不写出来研发会踩**。
|
|
562
|
+
跨平台通用的注意事项 → 上移到产品级概览的 ALWAYS/NEVER。
|
|
563
|
+
|
|
564
|
+
2️⃣ 写作模板
|
|
565
|
+
### {编号}. {一句话标题}
|
|
566
|
+
**现象**:{开发者会遇到什么具体表现}
|
|
567
|
+
**原因**:{为什么会这样,SDK / 平台机制层面}
|
|
568
|
+
**必须做**:{具体动作,可机械执行}
|
|
569
|
+
|
|
570
|
+
3️⃣ ✅ 正例(iOS)
|
|
571
|
+
### 1. AnyCancellable 必须存为实例属性
|
|
572
|
+
**现象**:.sink 闭包永远不触发,日志没有任何输出
|
|
573
|
+
**原因**:局部变量 cancellable 出作用域后被释放,Combine 自动解除订阅
|
|
574
|
+
**必须做**:声明 `private var cancellables = Set<AnyCancellable>()` 实例属性,
|
|
575
|
+
所有 sink 后接 `.store(in: &cancellables)`
|
|
576
|
+
|
|
577
|
+
### 2. sink 闭包必须显式 [weak self]
|
|
578
|
+
**现象**:VC dismiss 后 ViewModel 不释放,Memory Graph 显示循环引用
|
|
579
|
+
**原因**:sink 闭包对 self 强引用,publisher 又被 self 持有
|
|
580
|
+
**必须做**:所有 .sink { } 闭包第一行加 [weak self]
|
|
581
|
+
|
|
582
|
+
### 3. 首次申请麦克风权限的弹窗在异步线程触发会被忽略
|
|
583
|
+
**现象**:点击连麦按钮后,系统不弹权限对话框,SDK 直接返回权限拒绝
|
|
584
|
+
**原因**:iOS 权限弹窗必须在主线程触发,异步线程调用静默失败
|
|
585
|
+
**必须做**:`DispatchQueue.main.async { applyForSeat() }`
|
|
586
|
+
|
|
587
|
+
为什么这些是正例:
|
|
588
|
+
- 每条都是 iOS 独有(Android/Web 无 Combine、无 [weak self]、权限机制不同)
|
|
589
|
+
- 三段式结构(现象/原因/必须做)清晰,新人能快速 get
|
|
590
|
+
- "必须做" 是具体动作,不是"注意一下"
|
|
591
|
+
|
|
592
|
+
4️⃣ ❌ 反例
|
|
593
|
+
### 1. 注意内存管理
|
|
594
|
+
内存管理很重要,要避免泄漏。
|
|
595
|
+
→ "注意""很重要" = 软词;"内存管理"跨平台都有 → 不是平台特有
|
|
596
|
+
|
|
597
|
+
### 2. iOS 上需要权限
|
|
598
|
+
iOS 应用要在 Info.plist 声明权限。
|
|
599
|
+
→ 这是基础常识,不写也不会踩;且 base-setup 已覆盖
|
|
600
|
+
|
|
601
|
+
### 3. 异步代码要小心
|
|
602
|
+
处理异步代码时要注意时序问题。
|
|
603
|
+
→ 全是模糊形容词,无具体动作
|
|
604
|
+
|
|
605
|
+
5️⃣ 必填项语义三件套
|
|
606
|
+
- 违反后果:平台特有坑没写 → AI 生成代码在该平台报错 / 行为异常 / 内存泄漏
|
|
607
|
+
- 验证手段:每条必须含"必须做:{具体动作}";描述的现象其他平台不会出现;不出现"注意""小心""很重要"等软词
|
|
608
|
+
- 绕过条件:无(每个平台 slice 都至少要有 1 条)
|
|
120
609
|
-->
|
|
121
610
|
|
|
122
611
|
## 代码生成约束 [必填]
|
|
123
612
|
|
|
124
|
-
<!-- 指引:
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
613
|
+
<!-- 指引: 代码生成约束 [必填]
|
|
614
|
+
|
|
615
|
+
本 section 是给 AI 读的硬性规则,与「平台特有注意事项」互补:
|
|
616
|
+
- 注意事项 = 给人读的经验提醒(描述性)
|
|
617
|
+
- 代码生成约束 = 给 AI 读的可机械验证规则(结构化)
|
|
618
|
+
|
|
619
|
+
⚠️ 核心原则
|
|
620
|
+
**MUST 的语义 = 它的 backtick 符号能验的语义。**
|
|
621
|
+
规则文字承诺得比 backtick 多 → 维度溢出 → AI 写对了 grep 不到,写错了也 grep 不到 → verifier 反向变成攻击面。
|
|
622
|
+
|
|
623
|
+
完整原则与红旗词表见 slice-spec.md「MUST 规则的维度对齐原则」,但你**不需要先读它**——按下方批注的模板和正反例即可。
|
|
624
|
+
<!-- 指引: 代码生成约束 [必填]
|
|
625
|
+
|
|
626
|
+
本 section 是给 AI 读的硬性规则,与「平台特有注意事项」互补:
|
|
627
|
+
- 注意事项 = 给人读的经验提醒(描述性)
|
|
628
|
+
- 代码生成约束 = 给 AI 读的可机械验证规则(结构化)
|
|
629
|
+
|
|
630
|
+
⚠️ 核心原则
|
|
631
|
+
**MUST 的语义 = 它的 backtick 符号能验的语义。**
|
|
632
|
+
规则文字承诺得比 backtick 多 → 维度溢出 → AI 写对了 grep 不到,写错了也 grep 不到 → verifier 反向变成攻击面。
|
|
633
|
+
|
|
634
|
+
完整原则与红旗词表见 slice-spec.md「MUST 规则的维度对齐原则」,但你**不需要先读它**——按下方批注的模板和正反例即可。
|
|
135
635
|
-->
|
|
136
636
|
|
|
137
637
|
### 编译必要条件 [必填]
|
|
138
638
|
|
|
139
|
-
<!-- 指引:
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
639
|
+
<!-- 指引: 编译必要条件 [必填]
|
|
640
|
+
|
|
641
|
+
1️⃣ 你必须写什么
|
|
642
|
+
本 slice 代码能编译通过的最小条件。**只写增量条件**(通用条件见 login-auth)。
|
|
643
|
+
|
|
644
|
+
2️⃣ 写作模板
|
|
645
|
+
- **必须导入** `{包名 1}` / `{包名 2}` —— SDK 类型不可用则编译失败。
|
|
646
|
+
- **最低 SDK 版本**:`{version}`(若高于 base-setup 中的版本)
|
|
647
|
+
- **必须的权限声明**:
|
|
648
|
+
- {平台}: {key/permission} —— {用途}
|
|
649
|
+
|
|
650
|
+
3️⃣ ✅ 正例(摘自 live/ios/coguest-apply)
|
|
651
|
+
- **必须导入** `import TencentImSDKPlugin` 与 `import Combine`
|
|
652
|
+
- **最低 iOS 版本**:`13.0`(Combine 最低要求)
|
|
653
|
+
- **必须的权限声明**:
|
|
654
|
+
- Info.plist `NSMicrophoneUsageDescription` —— 连麦需要麦克风
|
|
655
|
+
- Info.plist `NSCameraUsageDescription` —— 连麦需要摄像头
|
|
656
|
+
|
|
657
|
+
4️⃣ ❌ 反例
|
|
658
|
+
- 需要导入相关的包。
|
|
659
|
+
- 最低版本参见官方文档。
|
|
660
|
+
- 注意申请权限。
|
|
661
|
+
→ 模糊、不可机械验证、"参见官方文档" = 等于没写
|
|
144
662
|
|
|
145
|
-
|
|
663
|
+
5️⃣ 必填项语义三件套
|
|
664
|
+
- 违反后果:编译条件不明 → AI 生成代码编译失败 → 客户接入第一步就卡住
|
|
665
|
+
- 验证手段:每条都有 backtick 包裹的具体包名/版本号/权限 key
|
|
666
|
+
- 绕过条件:同 login-auth,无额外要求 → 写"同 login-auth,无额外要求"
|
|
667
|
+
<!-- 指引: 编译必要条件 [必填]
|
|
668
|
+
|
|
669
|
+
1️⃣ 你必须写什么
|
|
670
|
+
本 slice 代码能编译通过的最小条件。**只写增量条件**(通用条件见 login-auth)。
|
|
671
|
+
|
|
672
|
+
2️⃣ 写作模板
|
|
673
|
+
- **必须导入** `{包名 1}` / `{包名 2}` —— SDK 类型不可用则编译失败。
|
|
674
|
+
- **最低 SDK 版本**:`{version}`(若高于 base-setup 中的版本)
|
|
675
|
+
- **必须的权限声明**:
|
|
676
|
+
- {平台}: {key/permission} —— {用途}
|
|
677
|
+
|
|
678
|
+
3️⃣ ✅ 正例(摘自 live/ios/coguest-apply)
|
|
679
|
+
- **必须导入** `import TencentImSDKPlugin` 与 `import Combine`
|
|
680
|
+
- **最低 iOS 版本**:`13.0`(Combine 最低要求)
|
|
681
|
+
- **必须的权限声明**:
|
|
682
|
+
- Info.plist `NSMicrophoneUsageDescription` —— 连麦需要麦克风
|
|
683
|
+
- Info.plist `NSCameraUsageDescription` —— 连麦需要摄像头
|
|
684
|
+
|
|
685
|
+
4️⃣ ❌ 反例
|
|
686
|
+
- 需要导入相关的包。
|
|
687
|
+
- 最低版本参见官方文档。
|
|
688
|
+
- 注意申请权限。
|
|
689
|
+
→ 模糊、不可机械验证、"参见官方文档" = 等于没写
|
|
690
|
+
|
|
691
|
+
5️⃣ 必填项语义三件套
|
|
692
|
+
- 违反后果:编译条件不明 → AI 生成代码编译失败 → 客户接入第一步就卡住
|
|
693
|
+
- 验证手段:每条都有 backtick 包裹的具体包名/版本号/权限 key
|
|
694
|
+
- 绕过条件:同 login-auth,无额外要求 → 写"同 login-auth,无额外要求"
|
|
146
695
|
-->
|
|
147
696
|
|
|
148
697
|
### 生成规则 [必填]
|
|
149
698
|
|
|
150
|
-
#### MUST
|
|
699
|
+
#### MUST(生成时必须包含)
|
|
700
|
+
|
|
701
|
+
<!-- 指引: MUST [必填,至少 3 条]
|
|
702
|
+
|
|
703
|
+
1️⃣ 你必须写什么
|
|
704
|
+
AI 生成代码时**机械验证**的硬约束,**只写 apply 能用 grep 验的规则**。
|
|
705
|
+
|
|
706
|
+
2️⃣ 写作模板
|
|
707
|
+
1. **必须 {强动词} `{可 grep 的符号}`** —— {不这样做的具体后果}。
|
|
708
|
+
**Verify**: 检查 `{符号}` 出现 ≥1 次。
|
|
709
|
+
|
|
710
|
+
2. **必须 {强动词} `{符号 A}` 与 `{符号 B}`** —— {后果}。
|
|
711
|
+
**Verify**: 检查 `{符号 A}` 与 `{符号 B}` 各出现 ≥1 次。
|
|
712
|
+
|
|
713
|
+
3. **必须在 {场景} 时调用 `{符号}`** —— {后果}。
|
|
714
|
+
**Verify**: 检查 `{符号}` 出现 ≥1 次。
|
|
715
|
+
|
|
716
|
+
⚠️ 「在 X 时调用 Y」中的 X 语义 apply **不验**,只验 Y 出现。
|
|
717
|
+
这是有意的——调用时机属于软规则,放到「调用时序」section 引导 AI。
|
|
718
|
+
|
|
719
|
+
3️⃣ ✅ 正例(摘自 chat/ios/multi-instance)
|
|
720
|
+
1. **必须导入 `import TencentImSDKPlugin`** —— 否则 SDK 类型不可用,编译报错。
|
|
721
|
+
**Verify**: 检查 `import TencentImSDKPlugin` 出现 ≥1 次。
|
|
722
|
+
|
|
723
|
+
2. **必须注册互踢监听 `addSimpleMsgListener`** —— 不注册则用户被踢后无感知。
|
|
724
|
+
**Verify**: 检查 `addSimpleMsgListener` 出现 ≥1 次。
|
|
725
|
+
|
|
726
|
+
3. **必须在 `onKickedOffline` 回调里展示 UI 反馈 `errorMessage`** ——
|
|
727
|
+
仅 print 不算,用户看不到。
|
|
728
|
+
**Verify**: 检查 `onKickedOffline` 与 `errorMessage` 各出现 ≥1 次。
|
|
729
|
+
|
|
730
|
+
为什么是正例:
|
|
731
|
+
- 每条用强动词("必须导入""必须注册"),不用"应该""建议"
|
|
732
|
+
- backtick 内是**精确的可 grep 字符串**(类名/方法名)
|
|
733
|
+
- 规则文字承诺的范围 ≤ Verify 能验的范围(无维度溢出)
|
|
734
|
+
- 每条都有"违反后果"
|
|
735
|
+
|
|
736
|
+
4️⃣ ❌ 反例(及红旗词诊断)
|
|
737
|
+
1. **应该正确处理互踢回调** —— 否则用户体验不好。
|
|
738
|
+
**Verify**: 检查互踢逻辑是否完整。
|
|
739
|
+
↑ 软词"应该" + 模糊动词"处理" + Verify 不可机械化
|
|
740
|
+
|
|
741
|
+
2. **必须调用 `login()` 或 `loginWithSig()`** —— 没登录无法用 SDK。
|
|
742
|
+
**Verify**: 检查 `login` 出现。
|
|
743
|
+
↑ "或" = 红旗词;只 grep 一个 ≠ 验了选择
|
|
744
|
+
|
|
745
|
+
3. **必须按业务场景选择互踢策略** —— 业务决定。
|
|
746
|
+
**Verify**: 检查策略配置是否合理。
|
|
747
|
+
↑ "按业务""合理" = 不可机械验证,应下沉到「最佳实践」软规则
|
|
151
748
|
|
|
152
|
-
|
|
749
|
+
🚩 红旗词表(出现任一即重写)
|
|
750
|
+
- 「或 / 任一」 → 拆两条 MUST 各管一个分支
|
|
751
|
+
- 「等价 / 或类似」 → 显式枚举所有可接受写法
|
|
752
|
+
- 「按业务 / 根据场景」 → 完全移出 MUST,移到「代码示例」按场景给完整 demo
|
|
753
|
+
- 「留给 / 负责」 → 移到「集成检查点」,作为 AI 读但 apply 不验的引导
|
|
754
|
+
- 「多 backtick 但 Verify 只提一个」 → 拆原子规则;调用顺序写到「调用时序」
|
|
153
755
|
|
|
154
|
-
|
|
155
|
-
|
|
756
|
+
✍️ 自查三问(写完每条 MUST 之前问自己)
|
|
757
|
+
1. backtick 里的符号是不是 verify 唯一会做的事?规则文字其他词能不能删?
|
|
758
|
+
2. 如果 AI 写**等价但不同写法**的代码,verify 会不会误杀?误杀 = 规则太死。
|
|
759
|
+
3. 如果 AI 写**只满足 backtick 字符串但语义错**的代码,verify 会不会放过?放过 = 规则太松。
|
|
156
760
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
761
|
+
5️⃣ 必填项语义三件套
|
|
762
|
+
- 违反后果:MUST 含红旗词 → apply 误杀正确代码 + 训练 AI 凑字符串 → slice 不可合并(2024-12 真实事故:room-lifecycle 写"调 A 或 B",apply 验过却生成错误混合代码)
|
|
763
|
+
- 验证手段:python scripts/check_must_rules.py {file}
|
|
764
|
+
通过标准:红旗词命中 0 次;每条 MUST 都有 Verify;Verify 内有 backtick
|
|
765
|
+
- 绕过条件:**无**。MUST 是硬约束区,不接受任何豁免。需要"或/按业务"语义 → 拆原子规则,或下沉到「最佳实践」软规则区
|
|
766
|
+
#### MUST(生成时必须包含)
|
|
161
767
|
|
|
162
|
-
|
|
163
|
-
— 「或 / 任一」、「等价 / 或类似」、「按业务 / 根据场景」
|
|
164
|
-
— 「留给 / 负责」、「多 backtick 但 Verify 只提一个」
|
|
768
|
+
<!-- 指引: MUST [必填,至少 3 条]
|
|
165
769
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
**Verify**: 检查是否存在 `useRoomState`。
|
|
770
|
+
1️⃣ 你必须写什么
|
|
771
|
+
AI 生成代码时**机械验证**的硬约束,**只写 apply 能用 grep 验的规则**。
|
|
169
772
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
773
|
+
2️⃣ 写作模板
|
|
774
|
+
1. **必须 {强动词} `{可 grep 的符号}`** —— {不这样做的具体后果}。
|
|
775
|
+
**Verify**: 检查 `{符号}` 出现 ≥1 次。
|
|
173
776
|
|
|
174
|
-
|
|
175
|
-
|
|
777
|
+
2. **必须 {强动词} `{符号 A}` 与 `{符号 B}`** —— {后果}。
|
|
778
|
+
**Verify**: 检查 `{符号 A}` 与 `{符号 B}` 各出现 ≥1 次。
|
|
779
|
+
|
|
780
|
+
3. **必须在 {场景} 时调用 `{符号}`** —— {后果}。
|
|
781
|
+
**Verify**: 检查 `{符号}` 出现 ≥1 次。
|
|
782
|
+
|
|
783
|
+
⚠️ 「在 X 时调用 Y」中的 X 语义 apply **不验**,只验 Y 出现。
|
|
784
|
+
这是有意的——调用时机属于软规则,放到「调用时序」section 引导 AI。
|
|
785
|
+
|
|
786
|
+
3️⃣ ✅ 正例(摘自 chat/ios/multi-instance)
|
|
787
|
+
1. **必须导入 `import TencentImSDKPlugin`** —— 否则 SDK 类型不可用,编译报错。
|
|
788
|
+
**Verify**: 检查 `import TencentImSDKPlugin` 出现 ≥1 次。
|
|
789
|
+
|
|
790
|
+
2. **必须注册互踢监听 `addSimpleMsgListener`** —— 不注册则用户被踢后无感知。
|
|
791
|
+
**Verify**: 检查 `addSimpleMsgListener` 出现 ≥1 次。
|
|
792
|
+
|
|
793
|
+
3. **必须在 `onKickedOffline` 回调里展示 UI 反馈 `errorMessage`** ——
|
|
794
|
+
仅 print 不算,用户看不到。
|
|
795
|
+
**Verify**: 检查 `onKickedOffline` 与 `errorMessage` 各出现 ≥1 次。
|
|
796
|
+
|
|
797
|
+
为什么是正例:
|
|
798
|
+
- 每条用强动词("必须导入""必须注册"),不用"应该""建议"
|
|
799
|
+
- backtick 内是**精确的可 grep 字符串**(类名/方法名)
|
|
800
|
+
- 规则文字承诺的范围 ≤ Verify 能验的范围(无维度溢出)
|
|
801
|
+
- 每条都有"违反后果"
|
|
802
|
+
|
|
803
|
+
4️⃣ ❌ 反例(及红旗词诊断)
|
|
804
|
+
1. **应该正确处理互踢回调** —— 否则用户体验不好。
|
|
805
|
+
**Verify**: 检查互踢逻辑是否完整。
|
|
806
|
+
↑ 软词"应该" + 模糊动词"处理" + Verify 不可机械化
|
|
807
|
+
|
|
808
|
+
2. **必须调用 `login()` 或 `loginWithSig()`** —— 没登录无法用 SDK。
|
|
809
|
+
**Verify**: 检查 `login` 出现。
|
|
810
|
+
↑ "或" = 红旗词;只 grep 一个 ≠ 验了选择
|
|
811
|
+
|
|
812
|
+
3. **必须按业务场景选择互踢策略** —— 业务决定。
|
|
813
|
+
**Verify**: 检查策略配置是否合理。
|
|
814
|
+
↑ "按业务""合理" = 不可机械验证,应下沉到「最佳实践」软规则
|
|
815
|
+
|
|
816
|
+
🚩 红旗词表(出现任一即重写)
|
|
817
|
+
- 「或 / 任一」 → 拆两条 MUST 各管一个分支
|
|
818
|
+
- 「等价 / 或类似」 → 显式枚举所有可接受写法
|
|
819
|
+
- 「按业务 / 根据场景」 → 完全移出 MUST,移到「代码示例」按场景给完整 demo
|
|
820
|
+
- 「留给 / 负责」 → 移到「集成检查点」,作为 AI 读但 apply 不验的引导
|
|
821
|
+
- 「多 backtick 但 Verify 只提一个」 → 拆原子规则;调用顺序写到「调用时序」
|
|
822
|
+
|
|
823
|
+
✍️ 自查三问(写完每条 MUST 之前问自己)
|
|
824
|
+
1. backtick 里的符号是不是 verify 唯一会做的事?规则文字其他词能不能删?
|
|
825
|
+
2. 如果 AI 写**等价但不同写法**的代码,verify 会不会误杀?误杀 = 规则太死。
|
|
826
|
+
3. 如果 AI 写**只满足 backtick 字符串但语义错**的代码,verify 会不会放过?放过 = 规则太松。
|
|
827
|
+
|
|
828
|
+
5️⃣ 必填项语义三件套
|
|
829
|
+
- 违反后果:MUST 含红旗词 → apply 误杀正确代码 + 训练 AI 凑字符串 → slice 不可合并(2024-12 真实事故:room-lifecycle 写"调 A 或 B",apply 验过却生成错误混合代码)
|
|
830
|
+
- 验证手段:python scripts/check_must_rules.py {file}
|
|
831
|
+
通过标准:红旗词命中 0 次;每条 MUST 都有 Verify;Verify 内有 backtick
|
|
832
|
+
- 绕过条件:**无**。MUST 是硬约束区,不接受任何豁免。需要"或/按业务"语义 → 拆原子规则,或下沉到「最佳实践」软规则区
|
|
176
833
|
-->
|
|
177
834
|
|
|
178
|
-
#### MUST NOT
|
|
835
|
+
#### MUST NOT(生成时绝不能出现)
|
|
836
|
+
|
|
837
|
+
<!-- 指引: MUST NOT [必填,至少 2 条]
|
|
838
|
+
|
|
839
|
+
1️⃣ 你必须写什么
|
|
840
|
+
列出**绝不允许出现**的代码模式。重点写「看起来能跑但逻辑错误」的写法 —— 编译器抓不到,只有了解业务语义才能避免。
|
|
841
|
+
|
|
842
|
+
2️⃣ 写作模板
|
|
843
|
+
1. **不要 {动作} `{符号}`** —— {违反后果}。
|
|
844
|
+
**Verify**: 检查 `{符号}` 出现 0 次(或在特定上下文中出现 0 次)。
|
|
845
|
+
|
|
846
|
+
3️⃣ ✅ 正例
|
|
847
|
+
1. **不要在 `onKickedOffline` 回调里调用 `login()`** —— 自动重登形成两端死循环互踢,
|
|
848
|
+
最终两端都登不上。
|
|
849
|
+
**Verify**: 在 `onKickedOffline` 函数体内,`login` 出现 0 次。
|
|
850
|
+
|
|
851
|
+
2. **不要在客户端代码里硬编码 `SecretKey`** —— 密钥泄露后可签发任意 UserSig。
|
|
852
|
+
**Verify**: 全文 `SecretKey` 出现 0 次。
|
|
853
|
+
|
|
854
|
+
3. **不要把 `leaveRoom()` 当成解散会议** —— 房主离开后房间仍在,其他成员卡死。
|
|
855
|
+
**Verify**: 房主代码路径中,房主收口必须用 `endRoom`,不能用 `leaveRoom`。
|
|
856
|
+
|
|
857
|
+
4. **不要用 `try?` 吞掉 `loginWithSig` 的错误** —— 静默失败导致后续 API 全失败但无日志可查。
|
|
858
|
+
**Verify**: `try?\\s+.*loginWithSig` 出现 0 次(grep -E)。
|
|
859
|
+
|
|
860
|
+
为什么是正例:
|
|
861
|
+
- 每条精确到"哪个上下文里不能出现哪个符号"
|
|
862
|
+
- Verify 是 0 次匹配,机械可验
|
|
863
|
+
|
|
864
|
+
4️⃣ ❌ 反例
|
|
865
|
+
1. 不要写不安全的代码。
|
|
866
|
+
2. 避免循环引用。
|
|
867
|
+
3. 不要忽略错误。
|
|
868
|
+
→ 全部模糊,无 backtick,无 Verify,grep 不到
|
|
869
|
+
|
|
870
|
+
5️⃣ 必填项语义三件套
|
|
871
|
+
- 违反后果:MUST NOT 缺失或模糊 → AI 生成代码引入安全/性能/稳定性问题
|
|
872
|
+
- 验证手段:同 MUST,跑 python scripts/check_must_rules.py
|
|
873
|
+
- 绕过条件:无
|
|
874
|
+
#### MUST NOT(生成时绝不能出现)
|
|
875
|
+
|
|
876
|
+
<!-- 指引: MUST NOT [必填,至少 2 条]
|
|
877
|
+
|
|
878
|
+
1️⃣ 你必须写什么
|
|
879
|
+
列出**绝不允许出现**的代码模式。重点写「看起来能跑但逻辑错误」的写法 —— 编译器抓不到,只有了解业务语义才能避免。
|
|
179
880
|
|
|
180
|
-
|
|
181
|
-
|
|
881
|
+
2️⃣ 写作模板
|
|
882
|
+
1. **不要 {动作} `{符号}`** —— {违反后果}。
|
|
883
|
+
**Verify**: 检查 `{符号}` 出现 0 次(或在特定上下文中出现 0 次)。
|
|
182
884
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
885
|
+
3️⃣ ✅ 正例
|
|
886
|
+
1. **不要在 `onKickedOffline` 回调里调用 `login()`** —— 自动重登形成两端死循环互踢,
|
|
887
|
+
最终两端都登不上。
|
|
888
|
+
**Verify**: 在 `onKickedOffline` 函数体内,`login` 出现 0 次。
|
|
186
889
|
|
|
187
|
-
|
|
188
|
-
|
|
890
|
+
2. **不要在客户端代码里硬编码 `SecretKey`** —— 密钥泄露后可签发任意 UserSig。
|
|
891
|
+
**Verify**: 全文 `SecretKey` 出现 0 次。
|
|
892
|
+
|
|
893
|
+
3. **不要把 `leaveRoom()` 当成解散会议** —— 房主离开后房间仍在,其他成员卡死。
|
|
894
|
+
**Verify**: 房主代码路径中,房主收口必须用 `endRoom`,不能用 `leaveRoom`。
|
|
895
|
+
|
|
896
|
+
4. **不要用 `try?` 吞掉 `loginWithSig` 的错误** —— 静默失败导致后续 API 全失败但无日志可查。
|
|
897
|
+
**Verify**: `try?\\s+.*loginWithSig` 出现 0 次(grep -E)。
|
|
898
|
+
|
|
899
|
+
为什么是正例:
|
|
900
|
+
- 每条精确到"哪个上下文里不能出现哪个符号"
|
|
901
|
+
- Verify 是 0 次匹配,机械可验
|
|
902
|
+
|
|
903
|
+
4️⃣ ❌ 反例
|
|
904
|
+
1. 不要写不安全的代码。
|
|
905
|
+
2. 避免循环引用。
|
|
906
|
+
3. 不要忽略错误。
|
|
907
|
+
→ 全部模糊,无 backtick,无 Verify,grep 不到
|
|
908
|
+
|
|
909
|
+
5️⃣ 必填项语义三件套
|
|
910
|
+
- 违反后果:MUST NOT 缺失或模糊 → AI 生成代码引入安全/性能/稳定性问题
|
|
911
|
+
- 验证手段:同 MUST,跑 python scripts/check_must_rules.py
|
|
912
|
+
- 绕过条件:无
|
|
189
913
|
-->
|
|
190
914
|
|
|
191
915
|
### 集成检查点 [必填]
|
|
192
916
|
|
|
193
|
-
<!-- 指引:
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
917
|
+
<!-- 指引: 集成检查点 [必填,至少 3 条]
|
|
918
|
+
|
|
919
|
+
1️⃣ 你必须写什么
|
|
920
|
+
假设目标是已有项目(不是从零开始的 demo),列出集成时需要确认的事项。
|
|
921
|
+
本 section 是软规则区(apply 不验),AI 阅读后自行判断。
|
|
922
|
+
|
|
923
|
+
2️⃣ 写作模板
|
|
924
|
+
- 是否与项目已有 SDK 初始化冲突?(检查 `{初始化函数}` 是否已在别处调用)
|
|
925
|
+
- 是否依赖其他 slice 的前置状态?(本 slice 依赖 → `{slice-id}`)
|
|
926
|
+
- 对已有代码的侵入性:`{新增 X 个文件 / 修改 Y 个文件}`
|
|
927
|
+
- {本 slice 特有的集成关注点}
|
|
928
|
+
|
|
929
|
+
3️⃣ ✅ 正例
|
|
930
|
+
- 是否与项目已有 SDK 初始化冲突?检查项目中 `V2TIMManager.sharedInstance().initSDK()`
|
|
931
|
+
是否已被调用,若是则不要重复调用
|
|
932
|
+
- 是否依赖其他 slice?依赖 `chat/login-auth` 完成登录,依赖 `live/room-lifecycle` 已进房
|
|
933
|
+
- 对已有代码的侵入性:新增 1 个 ViewModel 文件,无需修改现有代码
|
|
934
|
+
- 是否在已有的 RoomEvent 监听基础上叠加?如已注册 `onUserSigExpired` 监听,本 slice 注册的是不同事件,可叠加;若已注册 `onKickedOffline`,需合并而非新增
|
|
935
|
+
|
|
936
|
+
4️⃣ ❌ 反例
|
|
937
|
+
- 集成时注意一下 SDK 冲突。
|
|
938
|
+
- 看看有没有依赖。
|
|
939
|
+
- 影响应该不大。
|
|
940
|
+
→ "注意一下""看看""应该不大" = 软词,无可操作信息
|
|
941
|
+
|
|
942
|
+
5️⃣ 必填项语义三件套
|
|
943
|
+
- 违反后果:不写检查点 → 集成时与已有代码冲突(双重初始化、状态污染)→ 客户报"按文档接但跑不起来"
|
|
944
|
+
- 验证手段:必须有 ≥3 条;每条引用具体函数/slice/文件数
|
|
945
|
+
- 绕过条件:无
|
|
946
|
+
<!-- 指引: 集成检查点 [必填,至少 3 条]
|
|
947
|
+
|
|
948
|
+
1️⃣ 你必须写什么
|
|
949
|
+
假设目标是已有项目(不是从零开始的 demo),列出集成时需要确认的事项。
|
|
950
|
+
本 section 是软规则区(apply 不验),AI 阅读后自行判断。
|
|
951
|
+
|
|
952
|
+
2️⃣ 写作模板
|
|
953
|
+
- 是否与项目已有 SDK 初始化冲突?(检查 `{初始化函数}` 是否已在别处调用)
|
|
954
|
+
- 是否依赖其他 slice 的前置状态?(本 slice 依赖 → `{slice-id}`)
|
|
955
|
+
- 对已有代码的侵入性:`{新增 X 个文件 / 修改 Y 个文件}`
|
|
956
|
+
- {本 slice 特有的集成关注点}
|
|
957
|
+
|
|
958
|
+
3️⃣ ✅ 正例
|
|
959
|
+
- 是否与项目已有 SDK 初始化冲突?检查项目中 `V2TIMManager.sharedInstance().initSDK()`
|
|
960
|
+
是否已被调用,若是则不要重复调用
|
|
961
|
+
- 是否依赖其他 slice?依赖 `chat/login-auth` 完成登录,依赖 `live/room-lifecycle` 已进房
|
|
962
|
+
- 对已有代码的侵入性:新增 1 个 ViewModel 文件,无需修改现有代码
|
|
963
|
+
- 是否在已有的 RoomEvent 监听基础上叠加?如已注册 `onUserSigExpired` 监听,本 slice 注册的是不同事件,可叠加;若已注册 `onKickedOffline`,需合并而非新增
|
|
964
|
+
|
|
965
|
+
4️⃣ ❌ 反例
|
|
966
|
+
- 集成时注意一下 SDK 冲突。
|
|
967
|
+
- 看看有没有依赖。
|
|
968
|
+
- 影响应该不大。
|
|
969
|
+
→ "注意一下""看看""应该不大" = 软词,无可操作信息
|
|
970
|
+
|
|
971
|
+
5️⃣ 必填项语义三件套
|
|
972
|
+
- 违反后果:不写检查点 → 集成时与已有代码冲突(双重初始化、状态污染)→ 客户报"按文档接但跑不起来"
|
|
973
|
+
- 验证手段:必须有 ≥3 条;每条引用具体函数/slice/文件数
|
|
974
|
+
- 绕过条件:无
|
|
198
975
|
-->
|
|
199
976
|
|
|
200
977
|
## 验证矩阵 [必填]
|
|
201
978
|
|
|
202
|
-
<!-- 指引:
|
|
979
|
+
<!-- 指引: 验证矩阵 [必填]
|
|
980
|
+
|
|
981
|
+
1️⃣ 你必须写什么
|
|
982
|
+
平台 slice 末尾的**统一验收出口**。AI 生成代码后或人工 review 时,自上而下跑一遍即可完成验收。
|
|
983
|
+
这是 SuperPowers「验证门」机制在 slice 层的落地——**禁止在没跑过验证矩阵的情况下声称完成**。
|
|
984
|
+
|
|
985
|
+
2️⃣ 4 个层级
|
|
986
|
+
- 1. 编译级:能编译、依赖齐全(CI / AI 自动)
|
|
987
|
+
- 2. 静态规则级:纯静态扫描 / grep 可查(CI / AI 自动)
|
|
988
|
+
- 3. 运行时级:跑起来通过日志锚点可观察(AI 半自动 / 人工)
|
|
989
|
+
- 4. 业务行为级:人眼看 UI / 硬件状态(人工)
|
|
990
|
+
|
|
991
|
+
要求(不可省):
|
|
992
|
+
- 每条「代码生成约束」MUST/MUST NOT 都要在矩阵中有对应行(层级 1 或 2)
|
|
993
|
+
- 至少 1 条层级 3 的检查,证明代码真能跑
|
|
994
|
+
- 至少 1 条层级 4 的检查,证明业务语义正确
|
|
995
|
+
|
|
996
|
+
3️⃣ ✅ 正例(摘自 live/ios/coguest-apply)
|
|
203
997
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
998
|
+
| 层级 | 检查项 | 验证手段 | 预期结果 |
|
|
999
|
+
|------|--------|----------|---------|
|
|
1000
|
+
| 1. 编译级 | 模块导入齐全 | xcodebuild build -scheme Demo | exit code 0 |
|
|
1001
|
+
| 1. 编译级 | iOS 最低版本 ≥ 13.0 | 查 Podfile/project.pbxproj | IPHONEOS_DEPLOYMENT_TARGET = 13.0 |
|
|
1002
|
+
| 2. 静态规则级 | 所有 sink 都 [weak self] | grep -E "sink\\s*\\{\\s*\\[weak self\\]" | 匹配数 == sink 总数 |
|
|
1003
|
+
| 2. 静态规则级 | AnyCancellable 是实例属性 | grep "var cancellables: Set<AnyCancellable>" | 至少 1 处 |
|
|
1004
|
+
| 2. 静态规则级 | 每个 .failure 有 errorMessage | grep -B 5 "case .failure" \| grep errorMessage | 无裸 print |
|
|
1005
|
+
| 3. 运行时级 | 申请发送成功 | 观众点申请 → 查日志 | [CoGuest] 申请已发送 |
|
|
1006
|
+
| 3. 运行时级 | 主播收到事件 | 主播端查日志 | onGuestApplicationReceived |
|
|
1007
|
+
| 3. 运行时级 | 超时 UI 反馈 | 主播不响应,等 30s | UI 展示"申请超时" |
|
|
1008
|
+
| 4. 业务行为级 | 通过前设备未开 | 点申请但未同意 | 摄像头指示灯不亮 |
|
|
1009
|
+
| 4. 业务行为级 | 断开后设备关闭 | 连麦中主动断开 | 摄像头指示灯熄灭 |
|
|
1010
|
+
|
|
1011
|
+
为什么是正例:
|
|
1012
|
+
- 4 层各有 ≥2 行,覆盖完整
|
|
1013
|
+
- 「检查项」都对应代码生成约束的 MUST/MUST NOT
|
|
1014
|
+
- 「验证手段」都是可执行命令或具体操作
|
|
1015
|
+
- 「预期结果」精确到字符串/状态/数值
|
|
209
1016
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
1017
|
+
4️⃣ ❌ 反例
|
|
1018
|
+
|
|
1019
|
+
| 层级 | 检查项 | 验证手段 | 预期结果 |
|
|
1020
|
+
|------|--------|----------|---------|
|
|
1021
|
+
| 1 | 能编译 | 编译看看 | 没报错 |
|
|
1022
|
+
| 2 | 代码规范 | 看一下代码 | 没问题 |
|
|
1023
|
+
|
|
1024
|
+
→ "看看""没问题" = 不可机械验证;层级 3、4 缺失;无对应 MUST
|
|
1025
|
+
|
|
1026
|
+
5️⃣ 必填项语义三件套
|
|
1027
|
+
- 违反后果:验证矩阵不全 → AI/人工无法系统性自验 → "应该没问题"上线 → 线上事故
|
|
1028
|
+
- 验证手段:python scripts/check_verify_matrix.py {file}
|
|
1029
|
+
通过标准:4 层各 ≥1 行;每条 MUST/MUST NOT 都能在层级 1 或 2 找到对应行;至少 1 条层级 3、1 条层级 4
|
|
1030
|
+
- 绕过条件:无
|
|
1031
|
+
<!-- 指引: 验证矩阵 [必填]
|
|
1032
|
+
|
|
1033
|
+
1️⃣ 你必须写什么
|
|
1034
|
+
平台 slice 末尾的**统一验收出口**。AI 生成代码后或人工 review 时,自上而下跑一遍即可完成验收。
|
|
1035
|
+
这是 SuperPowers「验证门」机制在 slice 层的落地——**禁止在没跑过验证矩阵的情况下声称完成**。
|
|
1036
|
+
|
|
1037
|
+
2️⃣ 4 个层级
|
|
1038
|
+
- 1. 编译级:能编译、依赖齐全(CI / AI 自动)
|
|
1039
|
+
- 2. 静态规则级:纯静态扫描 / grep 可查(CI / AI 自动)
|
|
1040
|
+
- 3. 运行时级:跑起来通过日志锚点可观察(AI 半自动 / 人工)
|
|
1041
|
+
- 4. 业务行为级:人眼看 UI / 硬件状态(人工)
|
|
1042
|
+
|
|
1043
|
+
要求(不可省):
|
|
1044
|
+
- 每条「代码生成约束」MUST/MUST NOT 都要在矩阵中有对应行(层级 1 或 2)
|
|
1045
|
+
- 至少 1 条层级 3 的检查,证明代码真能跑
|
|
1046
|
+
- 至少 1 条层级 4 的检查,证明业务语义正确
|
|
1047
|
+
|
|
1048
|
+
3️⃣ ✅ 正例(摘自 live/ios/coguest-apply)
|
|
1049
|
+
|
|
1050
|
+
| 层级 | 检查项 | 验证手段 | 预期结果 |
|
|
1051
|
+
|------|--------|----------|---------|
|
|
1052
|
+
| 1. 编译级 | 模块导入齐全 | xcodebuild build -scheme Demo | exit code 0 |
|
|
1053
|
+
| 1. 编译级 | iOS 最低版本 ≥ 13.0 | 查 Podfile/project.pbxproj | IPHONEOS_DEPLOYMENT_TARGET = 13.0 |
|
|
1054
|
+
| 2. 静态规则级 | 所有 sink 都 [weak self] | grep -E "sink\\s*\\{\\s*\\[weak self\\]" | 匹配数 == sink 总数 |
|
|
1055
|
+
| 2. 静态规则级 | AnyCancellable 是实例属性 | grep "var cancellables: Set<AnyCancellable>" | 至少 1 处 |
|
|
1056
|
+
| 2. 静态规则级 | 每个 .failure 有 errorMessage | grep -B 5 "case .failure" \| grep errorMessage | 无裸 print |
|
|
1057
|
+
| 3. 运行时级 | 申请发送成功 | 观众点申请 → 查日志 | [CoGuest] 申请已发送 |
|
|
1058
|
+
| 3. 运行时级 | 主播收到事件 | 主播端查日志 | onGuestApplicationReceived |
|
|
1059
|
+
| 3. 运行时级 | 超时 UI 反馈 | 主播不响应,等 30s | UI 展示"申请超时" |
|
|
1060
|
+
| 4. 业务行为级 | 通过前设备未开 | 点申请但未同意 | 摄像头指示灯不亮 |
|
|
1061
|
+
| 4. 业务行为级 | 断开后设备关闭 | 连麦中主动断开 | 摄像头指示灯熄灭 |
|
|
1062
|
+
|
|
1063
|
+
为什么是正例:
|
|
1064
|
+
- 4 层各有 ≥2 行,覆盖完整
|
|
1065
|
+
- 「检查项」都对应代码生成约束的 MUST/MUST NOT
|
|
1066
|
+
- 「验证手段」都是可执行命令或具体操作
|
|
1067
|
+
- 「预期结果」精确到字符串/状态/数值
|
|
1068
|
+
|
|
1069
|
+
4️⃣ ❌ 反例
|
|
1070
|
+
|
|
1071
|
+
| 层级 | 检查项 | 验证手段 | 预期结果 |
|
|
1072
|
+
|------|--------|----------|---------|
|
|
1073
|
+
| 1 | 能编译 | 编译看看 | 没报错 |
|
|
1074
|
+
| 2 | 代码规范 | 看一下代码 | 没问题 |
|
|
1075
|
+
|
|
1076
|
+
→ "看看""没问题" = 不可机械验证;层级 3、4 缺失;无对应 MUST
|
|
1077
|
+
|
|
1078
|
+
5️⃣ 必填项语义三件套
|
|
1079
|
+
- 违反后果:验证矩阵不全 → AI/人工无法系统性自验 → "应该没问题"上线 → 线上事故
|
|
1080
|
+
- 验证手段:python scripts/check_verify_matrix.py {file}
|
|
1081
|
+
通过标准:4 层各 ≥1 行;每条 MUST/MUST NOT 都能在层级 1 或 2 找到对应行;至少 1 条层级 3、1 条层级 4
|
|
1082
|
+
- 绕过条件:无
|
|
214
1083
|
-->
|
|
215
1084
|
|
|
216
1085
|
| 层级 | 检查项 | 验证手段 | 预期结果 |
|
|
@@ -224,10 +1093,49 @@ api_docs: # [必填] 该平台对应的 API 参考文档链
|
|
|
224
1093
|
|
|
225
1094
|
---
|
|
226
1095
|
|
|
227
|
-
## DoD
|
|
1096
|
+
## DoD 自查(提交前删除此 section)
|
|
1097
|
+
|
|
1098
|
+
<!-- 指引: 提交前对照 slice-spec.md 第五节「平台实现文件 DoD」逐条打勾。
|
|
1099
|
+
**任何一项未满足 = 未完成,不允许提 PR**。
|
|
1100
|
+
|
|
1101
|
+
⚠️ 仅打勾不跑命令 = 视为未验证。每条标了"验证命令"的项,必须在 PR 描述粘贴命令输出。
|
|
1102
|
+
|
|
1103
|
+
最关键的 5 个一票否决项:
|
|
1104
|
+
- [ ] api_docs 链接精确到类/模块级
|
|
1105
|
+
验证:python scripts/validate_api_docs.py {file}
|
|
1106
|
+
- [ ] 代码示例无 ... 省略,每个 .failure 有 errorMessage
|
|
1107
|
+
验证:grep -E "\\.\\.\\." {file} 命中 0 次
|
|
1108
|
+
- [ ] 代码生成约束 MUST 不含红旗词
|
|
1109
|
+
验证:python scripts/check_must_rules.py {file}
|
|
1110
|
+
- [ ] 验证矩阵 4 层齐全,覆盖所有 MUST/MUST NOT
|
|
1111
|
+
验证:python scripts/check_verify_matrix.py {file}
|
|
1112
|
+
- [ ] 平台特有注意事项 ≥ 1 条,每条含"必须做:"
|
|
1113
|
+
-->
|
|
1114
|
+
## DoD 自查(提交前删除此 section)
|
|
1115
|
+
|
|
1116
|
+
<!-- 指引: 提交前对照 slice-spec.md 第五节「平台实现文件 DoD」逐条打勾。
|
|
1117
|
+
**任何一项未满足 = 未完成,不允许提 PR**。
|
|
1118
|
+
|
|
1119
|
+
⚠️ 仅打勾不跑命令 = 视为未验证。每条标了"验证命令"的项,必须在 PR 描述粘贴命令输出。
|
|
1120
|
+
|
|
1121
|
+
最关键的 5 个一票否决项:
|
|
1122
|
+
- [ ] api_docs 链接精确到类/模块级
|
|
1123
|
+
验证:python scripts/validate_api_docs.py {file}
|
|
1124
|
+
- [ ] 代码示例无 ... 省略,每个 .failure 有 errorMessage
|
|
1125
|
+
验证:grep -E "\\.\\.\\." {file} 命中 0 次
|
|
1126
|
+
- [ ] 代码生成约束 MUST 不含红旗词
|
|
1127
|
+
验证:python scripts/check_must_rules.py {file}
|
|
1128
|
+
- [ ] 验证矩阵 4 层齐全,覆盖所有 MUST/MUST NOT
|
|
1129
|
+
验证:python scripts/check_verify_matrix.py {file}
|
|
1130
|
+
- [ ] 平台特有注意事项 ≥ 1 条,每条含"必须做:"
|
|
1131
|
+
-->
|
|
228
1132
|
|
|
229
|
-
提交前对照 `slice-spec.md` 第五节「平台实现文件 DoD
|
|
1133
|
+
提交前对照 `slice-spec.md` 第五节「平台实现文件 DoD」逐条打勾。任何一项未满足 = 未完成。
|
|
1134
|
+
提交前对照 `slice-spec.md` 第五节「平台实现文件 DoD」逐条打勾。任何一项未满足 = 未完成。
|
|
230
1135
|
|
|
231
1136
|
---
|
|
232
1137
|
|
|
233
|
-
>
|
|
1138
|
+
> **填写范例**:请参考 [`slices/live/ios/coguest-apply.md`](slices/live/ios/coguest-apply.md) — 这是目前最完整的平台 slice 实现,包含所有 section 的真实内容。
|
|
1139
|
+
> **完整规范**:见 [`slice-spec.md`](slice-spec.md) — 仅在批注不够用时回查。
|
|
1140
|
+
> **填写范例**:请参考 [`slices/live/ios/coguest-apply.md`](slices/live/ios/coguest-apply.md) — 这是目前最完整的平台 slice 实现,包含所有 section 的真实内容。
|
|
1141
|
+
> **完整规范**:见 [`slice-spec.md`](slice-spec.md) — 仅在批注不够用时回查。
|