@ngockhoale/ukit 3.0.0 → 3.0.2
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/CHANGELOG.md +13 -0
- package/manifests/documentation.yaml +75 -64
- package/manifests/engineConformance.yaml +32 -0
- package/manifests/hostCapabilities.yaml +2 -2
- package/manifests/instructionRules.yaml +55 -55
- package/manifests/platform.full.yaml +30 -4
- package/manifests/platform.user.yaml +4 -4
- package/package.json +8 -7
- package/scripts/bench/v3-ceremony.mjs +214 -0
- package/scripts/install/sync-installed-mirror.mjs +3 -3
- package/scripts/perf/audit-perf.mjs +9 -9
- package/scripts/perf/perf-findings.json +4 -4
- package/scripts/perf/perf-measure.md +20 -20
- package/src/cli/commands/doctor.js +38 -2
- package/src/core/buildPlan.js +3 -3
- package/src/core/compact/contextBudget.js +2 -2
- package/src/core/compact/threshold.js +3 -3
- package/src/core/docContracts.js +17 -17
- package/src/core/ensureGitignore.js +1 -1
- package/src/core/executionContracts.js +42 -2
- package/src/core/fileOps.js +3 -3
- package/src/core/gatewayProbe.js +2 -2
- package/src/core/gatewayResilienceEnv.js +2 -2
- package/src/core/handoffDocValidator.js +152 -0
- package/src/core/output/index.js +1 -1
- package/src/core/paths.js +2 -1
- package/src/core/reviewPanelAggregate.js +120 -0
- package/src/core/runInstallPipeline.js +6 -4
- package/src/core/runtimeConfig.js +13 -6
- package/src/core/sensitiveValueScanner.js +1 -1
- package/src/core/taskBudgetValidator.js +1 -1
- package/src/core/unattendedDoctor.js +1 -1
- package/src/core/update.js +1 -1
- package/src/index/buildIndex.js +2 -2
- package/src/index/impactCatalog.js +12 -12
- package/src/index/taskRouting.js +263 -5
- package/src/render/instructionRenderer.js +7 -7
- package/src/skill/auditSkill.js +1 -1
- package/{templates → template_project}/.claude/agents/code-reviewer.md +25 -0
- package/{templates → template_project}/.claude/agents/handoff-planner.md +17 -2
- package/{templates → template_project}/.claude/commands/ukit/handoff-create.md +1 -1
- package/{templates → template_project}/.claude/commands/ukit/handoff-fullstack.md +26 -6
- package/{templates → template_project}/.claude/commands/ukit/handoff-review.md +31 -6
- package/{templates → template_project}/.claude/hooks/handoff-model-guard.sh +1 -1
- package/{templates → template_project}/.claude/hooks/skill-router.sh +3 -3
- package/{templates → template_project}/.claude/skills/skill-quality/SKILL.md +1 -1
- package/{templates → template_project}/.claude/skills/skill-quality/pressure-scenario-template.md +1 -1
- package/template_project/.claude/ukit/index/handoff-doc-validator.mjs +193 -0
- package/{templates → template_project}/.claude/ukit/index/lib/index-core.mjs +12 -12
- package/template_project/.claude/ukit/index/review-panel-aggregate.mjs +174 -0
- package/{templates → template_project}/.claude/ukit/index/route-task.mjs +408 -12
- package/{templates → template_project}/.claude/ukit/index/unic-gateway.mjs +1 -1
- package/{templates → template_project}/.claude/ukit/runtime/execution-ledger.mjs +14 -5
- package/{templates → template_project}/.claude/ukit/runtime/safe-patch-core.mjs +3 -3
- package/{templates → template_project}/.claude/ukit/runtime/sensitive-value-scanner.mjs +1 -1
- package/{templates → template_project}/.claude/ukit/runtime/stop-coordinator.mjs +187 -8
- package/{templates → template_project}/.claude/ukit/runtime/task-watchdog.mjs +1 -1
- package/{templates → template_project}/.gitignore +2 -2
- package/{templates → template_project}/.omp/RULES.md +1 -1
- package/{templates → template_project}/.omp/agents/code-reviewer.md +27 -0
- package/{templates → template_project}/.omp/agents/handoff-planner.md +17 -2
- package/{templates → template_project}/.omp/config.yml +3 -3
- package/{templates → template_project}/AGENTS.md +2 -2
- package/{templates → template_project}/CLAUDE.md +2 -2
- package/{templates → template_project}/docs/AI_HANDOFF/RULES.md +1 -1
- package/{templates → template_project}/docs/UKIT_INTERNALS.md +3 -3
- package/{templates → template_project}/instructions/core.md +1 -1
- package/{templates → template_project}/instructions/layout.yaml +8 -8
- package/{templates → template_project}/instructions/overlays/claude.md +1 -1
- package/{templates → template_project}/instructions/overlays/repo.md +1 -1
- package/{templates → template_project}/ukit/storage/config.json +4 -1
- package/template_project/ukit/storage/memory/projects/.gitkeep +2 -0
- package/templates/ukit/storage/memory/projects/.gitkeep +0 -2
- /package/{templates → template_project}/.claude/agents/bug-debugger.md +0 -0
- /package/{templates → template_project}/.claude/agents/feature-implementer.md +0 -0
- /package/{templates → template_project}/.claude/agents/ukit-small-task-maintainer.md +0 -0
- /package/{templates → template_project}/.claude/agents/ukit-vision-analyst.md +0 -0
- /package/{templates → template_project}/.claude/commands/ukit/handoff-clear.md +0 -0
- /package/{templates → template_project}/.claude/commands/ukit/handoff-implement.md +0 -0
- /package/{templates → template_project}/.claude/commands/ukit/handoff-status.md +0 -0
- /package/{templates → template_project}/.claude/config/providers.md +0 -0
- /package/{templates → template_project}/.claude/hooks/auto-allow-bash.sh +0 -0
- /package/{templates → template_project}/.claude/hooks/auto-prune-bash.sh +0 -0
- /package/{templates → template_project}/.claude/hooks/block-dangerous.mjs +0 -0
- /package/{templates → template_project}/.claude/hooks/block-dangerous.sh +0 -0
- /package/{templates → template_project}/.claude/hooks/completion-gate.sh +0 -0
- /package/{templates → template_project}/.claude/hooks/compress-output.sh +0 -0
- /package/{templates → template_project}/.claude/hooks/context-hardcap-gate.sh +0 -0
- /package/{templates → template_project}/.claude/hooks/context-window-guard.sh +0 -0
- /package/{templates → template_project}/.claude/hooks/handoff-resume.sh +0 -0
- /package/{templates → template_project}/.claude/hooks/post-edit-verify.sh +0 -0
- /package/{templates → template_project}/.claude/hooks/pre-edit-backup.sh +0 -0
- /package/{templates → template_project}/.claude/hooks/project-important.sh +0 -0
- /package/{templates → template_project}/.claude/hooks/protect-files.sh +0 -0
- /package/{templates → template_project}/.claude/hooks/record-execution.mjs +0 -0
- /package/{templates → template_project}/.claude/hooks/record-execution.sh +0 -0
- /package/{templates → template_project}/.claude/hooks/reinject-context.sh +0 -0
- /package/{templates → template_project}/.claude/hooks/reset-compact-pressure.sh +0 -0
- /package/{templates → template_project}/.claude/hooks/sensitive-data-guard.mjs +0 -0
- /package/{templates → template_project}/.claude/hooks/sensitive-data-guard.sh +0 -0
- /package/{templates → template_project}/.claude/hooks/session-episode.sh +0 -0
- /package/{templates → template_project}/.claude/hooks/session-start.md +0 -0
- /package/{templates → template_project}/.claude/hooks/stale-spec-guard.sh +0 -0
- /package/{templates → template_project}/.claude/hooks/task-watchdog.sh +0 -0
- /package/{templates → template_project}/.claude/hooks/verification-guard.sh +0 -0
- /package/{templates → template_project}/.claude/hooks/vision-router.sh +0 -0
- /package/{templates → template_project}/.claude/settings.json +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/mce/mc.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/microsoft/wml-2010.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/microsoft/wml-2012.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/microsoft/wml-2018.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/microsoft/wml-cex-2018.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/microsoft/wml-cid-2016.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/schemas/microsoft/wml-symex-2015.xsd +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/scripts/pack.py +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/scripts/unpack.py +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/scripts/validate.py +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/scripts/validation/__init__.py +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/scripts/validation/base.py +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/scripts/validation/docx.py +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/scripts/validation/pptx.py +0 -0
- /package/{templates → template_project}/.claude/skills/_shared/ooxml/scripts/validation/redlining.py +0 -0
- /package/{templates → template_project}/.claude/skills/backend-api/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/LICENSE.txt +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/Lora-OFL.txt +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/Outfit-OFL.txt +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/Tektur-OFL.txt +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
- /package/{templates → template_project}/.claude/skills/canvas-design/philosophy-examples.md +0 -0
- /package/{templates → template_project}/.claude/skills/code-review/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/debugging-toolkit/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/debugging-toolkit/reference-tables.md +0 -0
- /package/{templates → template_project}/.claude/skills/delivery/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/discover-security/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/docker-packaging/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/docs-manager/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/docs-manager/conventions-and-examples.md +0 -0
- /package/{templates → template_project}/.claude/skills/docs-manager/init-project-docs.sh +0 -0
- /package/{templates → template_project}/.claude/skills/docs-manager/templates/README.md.template +0 -0
- /package/{templates → template_project}/.claude/skills/docs-manager/templates/agent-roles.md.template +0 -0
- /package/{templates → template_project}/.claude/skills/docs-manager/templates/coding-conventions.md.template +0 -0
- /package/{templates → template_project}/.claude/skills/docs-manager/templates/memory.md.template +0 -0
- /package/{templates → template_project}/.claude/skills/docs-manager/templates/onboarding.md.template +0 -0
- /package/{templates → template_project}/.claude/skills/docs-manager/templates/project.md.template +0 -0
- /package/{templates → template_project}/.claude/skills/docs-quality/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/docx/LICENSE.txt +0 -0
- /package/{templates → template_project}/.claude/skills/docx/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/docx/docx-js.md +0 -0
- /package/{templates → template_project}/.claude/skills/docx/ooxml.md +0 -0
- /package/{templates → template_project}/.claude/skills/docx/redlining-reference.md +0 -0
- /package/{templates → template_project}/.claude/skills/docx/scripts/__init__.py +0 -0
- /package/{templates → template_project}/.claude/skills/docx/scripts/document.py +0 -0
- /package/{templates → template_project}/.claude/skills/docx/scripts/templates/comments.xml +0 -0
- /package/{templates → template_project}/.claude/skills/docx/scripts/templates/commentsExtended.xml +0 -0
- /package/{templates → template_project}/.claude/skills/docx/scripts/templates/commentsExtensible.xml +0 -0
- /package/{templates → template_project}/.claude/skills/docx/scripts/templates/commentsIds.xml +0 -0
- /package/{templates → template_project}/.claude/skills/docx/scripts/templates/people.xml +0 -0
- /package/{templates → template_project}/.claude/skills/docx/scripts/utilities.py +0 -0
- /package/{templates → template_project}/.claude/skills/duraone/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/duraone/references/backend.md +0 -0
- /package/{templates → template_project}/.claude/skills/duraone/references/frontend.md +0 -0
- /package/{templates → template_project}/.claude/skills/duraone/references/sql.md +0 -0
- /package/{templates → template_project}/.claude/skills/duraone/references/workflow.md +0 -0
- /package/{templates → template_project}/.claude/skills/executing-plans/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/file-organizer/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/file-organizer/examples-and-practices.md +0 -0
- /package/{templates → template_project}/.claude/skills/frontend/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-design/LICENSE.txt +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-design/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Control/Box.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Control/Button.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Control/ButtonBar.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Control/ButtonFloat.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Control/CheckButton.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Control/Checkbox.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Control/Datetime.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Control/Dropdownlist.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Control/Input.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Control/Label.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Control/Master/BoxColumn.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Control/Popup/Confirm.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Control/Popup/Info.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Control/Popup/ModalInfo.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Control/Popup/Reject.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Control/Tag.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Control/Upload.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/ControlMobile/Dropdownlist.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/ControlMobile/PagingBar.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/ControlMobile/UploadImage.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Grid/AG.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Grid/AntTable.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Grid/CustomDropdownEditor.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Grid/CustomDropdownEditorEnable.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Grid/HtmlTable.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/PDFViewer.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Panel/FormView.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Partial/Footer.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Partial/Header.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Partial/Sidebar.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/Template.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/components/View/Form.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/composables/indexDBStore.js +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/composables/masterApi.js +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/composables/state.js +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/composables/useRequest.js +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/composables/useSession.js +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/composables/useTranslation.js +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/composables/useWebSocket.js +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/composables/userObj.js +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/composables/utils.js +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/reference/composables-example.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/reference/form-example.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/reference/grid-example.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/reference/masterdata-example/[id].vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/reference/masterdata-example/index.vue +0 -0
- /package/{templates → template_project}/.claude/skills/frontend-vue/reference/popup-example.vue +0 -0
- /package/{templates → template_project}/.claude/skills/next-step/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/pdf/LICENSE.txt +0 -0
- /package/{templates → template_project}/.claude/skills/pdf/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/pdf/forms.md +0 -0
- /package/{templates → template_project}/.claude/skills/pdf/reference.md +0 -0
- /package/{templates → template_project}/.claude/skills/pdf/scripts/check_bounding_boxes.py +0 -0
- /package/{templates → template_project}/.claude/skills/pdf/scripts/check_bounding_boxes_test.py +0 -0
- /package/{templates → template_project}/.claude/skills/pdf/scripts/check_fillable_fields.py +0 -0
- /package/{templates → template_project}/.claude/skills/pdf/scripts/convert_pdf_to_images.py +0 -0
- /package/{templates → template_project}/.claude/skills/pdf/scripts/create_validation_image.py +0 -0
- /package/{templates → template_project}/.claude/skills/pdf/scripts/extract_form_field_info.py +0 -0
- /package/{templates → template_project}/.claude/skills/pdf/scripts/fill_fillable_fields.py +0 -0
- /package/{templates → template_project}/.claude/skills/pdf/scripts/fill_pdf_form_with_annotations.py +0 -0
- /package/{templates → template_project}/.claude/skills/pdf-processing/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/pdf-processing-pro/FORMS.md +0 -0
- /package/{templates → template_project}/.claude/skills/pdf-processing-pro/OCR.md +0 -0
- /package/{templates → template_project}/.claude/skills/pdf-processing-pro/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/pdf-processing-pro/TABLES.md +0 -0
- /package/{templates → template_project}/.claude/skills/pdf-processing-pro/scripts/analyze_form.py +0 -0
- /package/{templates → template_project}/.claude/skills/pdf-processing-pro/workflows-and-troubleshooting.md +0 -0
- /package/{templates → template_project}/.claude/skills/postgres/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/postgres/reference/fn_get_examples.sql +0 -0
- /package/{templates → template_project}/.claude/skills/postgres/reference/fn_rpt_examples.sql +0 -0
- /package/{templates → template_project}/.claude/skills/postgres/reference/utility_functions.sql +0 -0
- /package/{templates → template_project}/.claude/skills/pptx/LICENSE.txt +0 -0
- /package/{templates → template_project}/.claude/skills/pptx/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/pptx/design-references.md +0 -0
- /package/{templates → template_project}/.claude/skills/pptx/html2pptx.md +0 -0
- /package/{templates → template_project}/.claude/skills/pptx/ooxml.md +0 -0
- /package/{templates → template_project}/.claude/skills/pptx/scripts/html2pptx.js +0 -0
- /package/{templates → template_project}/.claude/skills/pptx/scripts/inventory.py +0 -0
- /package/{templates → template_project}/.claude/skills/pptx/scripts/rearrange.py +0 -0
- /package/{templates → template_project}/.claude/skills/pptx/scripts/replace.py +0 -0
- /package/{templates → template_project}/.claude/skills/pptx/scripts/thumbnail.py +0 -0
- /package/{templates → template_project}/.claude/skills/pptx/template-replacement-reference.md +0 -0
- /package/{templates → template_project}/.claude/skills/pptx/utilities.md +0 -0
- /package/{templates → template_project}/.claude/skills/principle-attack-the-premise/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/principle-boundary-discipline/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/principle-encode-lessons-in-structure/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/principle-fix-root-causes/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/principle-foundational-thinking/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/principle-guard-the-context-window/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/principle-laziness-protocol/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/principle-minimize-reader-load/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/principle-model-the-domain/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/principle-never-block-on-the-human/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/principle-prove-it-works/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/principle-sequence-verifiable-units/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/principle-subtract-before-you-add/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/principle-test-behavior-not-implementation/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/project-learning/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/repo-maintenance/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/research/EXAMPLES.md +0 -0
- /package/{templates → template_project}/.claude/skills/research/REFERENCE.md +0 -0
- /package/{templates → template_project}/.claude/skills/research/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/root-cause-tracing/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/root-cause-tracing/diagrams.md +0 -0
- /package/{templates → template_project}/.claude/skills/root-cause-tracing/find-polluter.sh +0 -0
- /package/{templates → template_project}/.claude/skills/sharing-skills/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/sharing-skills/complete-example.md +0 -0
- /package/{templates → template_project}/.claude/skills/skill-quality/rationalization-table-template.md +0 -0
- /package/{templates → template_project}/.claude/skills/skill-quality/trigger-accuracy-template.md +0 -0
- /package/{templates → template_project}/.claude/skills/sql-optimization-patterns/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/sql-optimization-patterns/references/advanced-techniques.md +0 -0
- /package/{templates → template_project}/.claude/skills/sql-optimization-patterns/references/core-concepts.md +0 -0
- /package/{templates → template_project}/.claude/skills/sql-optimization-patterns/references/query-patterns.md +0 -0
- /package/{templates → template_project}/.claude/skills/subagent-driven-development/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/subagent-driven-development/example-workflow.md +0 -0
- /package/{templates → template_project}/.claude/skills/systematic-debugging/CREATION-LOG.md +0 -0
- /package/{templates → template_project}/.claude/skills/systematic-debugging/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/systematic-debugging/reference-tables.md +0 -0
- /package/{templates → template_project}/.claude/skills/systematic-debugging/test-academic.md +0 -0
- /package/{templates → template_project}/.claude/skills/systematic-debugging/test-pressure-1.md +0 -0
- /package/{templates → template_project}/.claude/skills/systematic-debugging/test-pressure-2.md +0 -0
- /package/{templates → template_project}/.claude/skills/systematic-debugging/test-pressure-3.md +0 -0
- /package/{templates → template_project}/.claude/skills/test-driven-development/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/test-driven-development/reference-tables.md +0 -0
- /package/{templates → template_project}/.claude/skills/testing-anti-patterns/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/testing-anti-patterns/reference-tables.md +0 -0
- /package/{templates → template_project}/.claude/skills/testing-quality/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/update-status/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/verification-before-completion/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/verification-before-completion/key-patterns.md +0 -0
- /package/{templates → template_project}/.claude/skills/webapp-testing/LICENSE.txt +0 -0
- /package/{templates → template_project}/.claude/skills/webapp-testing/SKILL.md +0 -0
- /package/{templates → template_project}/.claude/skills/webapp-testing/examples/console_logging.py +0 -0
- /package/{templates → template_project}/.claude/skills/webapp-testing/examples/element_discovery.py +0 -0
- /package/{templates → template_project}/.claude/skills/webapp-testing/examples/static_html_automation.py +0 -0
- /package/{templates → template_project}/.claude/skills/webapp-testing/scripts/with_server.py +0 -0
- /package/{templates → template_project}/.claude/ukit/index/anchor-search.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/index/build-index.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/index/cache-utils.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/index/extract-image.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/index/impact-context.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/index/post-edit-verify.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/index/pre-edit-backup.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/index/provision-worktree.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/index/query-index.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/index/refresh-index.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/index/reset-auto-permissions.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/index/resolve-context.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/index/route-catalog.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/index/safe-patch.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/index/stale-spec-check.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/index/task-budget-validator.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/index/triage.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/index/verify-context.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/runtime/async-lock.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/runtime/compact-threshold.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/runtime/context-capacity.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/runtime/hook-chain-budget.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/runtime/hook-chain-runner.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/runtime/hook-field-salvage.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/runtime/hook-input.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/runtime/hook-input.sh +0 -0
- /package/{templates → template_project}/.claude/ukit/runtime/hook-payload-store.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/runtime/hook-process.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/runtime/hook-telemetry.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/runtime/hook-telemetry.sh +0 -0
- /package/{templates → template_project}/.claude/ukit/runtime/output-compression.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/runtime/project-important.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/runtime/reinject-context.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/runtime/text-profile.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/runtime/token-utils.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/runtime/transcript-tail.mjs +0 -0
- /package/{templates → template_project}/.claude/ukit/skill-router-state.json +0 -0
- /package/{templates → template_project}/.codex/README.md +0 -0
- /package/{templates → template_project}/.codex/settings.json +0 -0
- /package/{templates → template_project}/.omp/AGENTS.md +0 -0
- /package/{templates → template_project}/.omp/README.md +0 -0
- /package/{templates → template_project}/.omp/agents/bug-debugger.md +0 -0
- /package/{templates → template_project}/.omp/agents/feature-implementer.md +0 -0
- /package/{templates → template_project}/.omp/agents/ukit-small-task-maintainer.md +0 -0
- /package/{templates → template_project}/.omp/agents/ukit-vision-analyst.md +0 -0
- /package/{templates → template_project}/.omp/hooks/pre/ukit-bridge.js +0 -0
- /package/{templates → template_project}/.ukit/storage/cache/hook-latency/unknown.jsonl +0 -0
- /package/{templates → template_project}/PROJECT_IMPORTANT.md +0 -0
- /package/{templates → template_project}/adapter-presets/claude/settings.local.json +0 -0
- /package/{templates → template_project}/adapter-presets/codex/settings.local.json +0 -0
- /package/{templates → template_project}/docs/AI_HANDOFF/ACTIVE.md +0 -0
- /package/{templates → template_project}/docs/AI_HANDOFF/HISTORY.md +0 -0
- /package/{templates → template_project}/docs/AI_HANDOFF/INDEX.md +0 -0
- /package/{templates → template_project}/docs/AI_HANDOFF/PLAN.md +0 -0
- /package/{templates → template_project}/docs/AI_HANDOFF/SPEC.md +0 -0
- /package/{templates → template_project}/docs/AI_HANDOFF/archive/.gitkeep +0 -0
- /package/{templates → template_project}/docs/AI_HANDOFF/tasks/.gitkeep +0 -0
- /package/{templates → template_project}/docs/AI_HANDOFF/tasks/_TEMPLATE.md +0 -0
- /package/{templates → template_project}/docs/BUGFIX.md +0 -0
- /package/{templates → template_project}/docs/BUG_INDEX.md +0 -0
- /package/{templates → template_project}/docs/BUG_METRICS.md +0 -0
- /package/{templates → template_project}/docs/BUG_TEMPLATE.md +0 -0
- /package/{templates → template_project}/docs/CODE_MAP.md +0 -0
- /package/{templates → template_project}/docs/MEMORY.md +0 -0
- /package/{templates → template_project}/docs/PROJECT.md +0 -0
- /package/{templates → template_project}/docs/PROMPT_CACHING.md +0 -0
- /package/{templates → template_project}/docs/WORKLOG.md +0 -0
- /package/{templates → template_project}/instructions/overlays/agents.md +0 -0
- /package/{templates → template_project}/instructions/overlays/omp-rules.md +0 -0
- /package/{templates → template_project}/instructions/repo-vars.yaml +0 -0
- /package/{templates → template_project}/ukit/README.md +0 -0
- /package/{templates → template_project}/ukit/storage/cache/compact-history.json +0 -0
- /package/{templates → template_project}/ukit/storage/cache/compact-pressure.json +0 -0
- /package/{templates → template_project}/ukit/storage/cache/output-history.json +0 -0
- /package/{templates → template_project}/ukit/storage/cache/prompt-cache.json +0 -0
- /package/{templates → template_project}/ukit/storage/memory/sessions/.gitkeep +0 -0
- /package/{templates → template_project}/ukit/storage/memory/user.json +0 -0
- /package/{templates/user → template_user}/README.md +0 -0
- /package/{templates/user → template_user}/playbooks/bug-fix.md +0 -0
- /package/{templates/user → template_user}/playbooks/issue-implementation.md +0 -0
- /package/{templates/user → template_user}/storage/config.json +0 -0
|
@@ -69,6 +69,29 @@ export const ROUTE_INTENT_KINDS = new Set(['informational', 'delivery', 'mutatio
|
|
|
69
69
|
export const ROUTE_MUTABILITIES = new Set(['read-only', 'mutating', 'mixed']);
|
|
70
70
|
export const ROUTE_RIGOR_LEVELS = new Set(['R0', 'R1', 'R2', 'R3', 'R4']);
|
|
71
71
|
export const ROUTE_MODEL_TIERS = new Set(['lite', 'code', 'smart']);
|
|
72
|
+
export const ROUTE_RISK_FLOORS = new Set(['none', 'high-risk']);
|
|
73
|
+
export const ROUTE_EFFORTS = new Set(['low', 'medium', 'high']);
|
|
74
|
+
// SPEC §5 FR-003: fixed table order — codes are emitted and printed in this order.
|
|
75
|
+
// The first six raise the floor to 'high-risk'; the last two are informational only.
|
|
76
|
+
export const ROUTE_RISK_REASON_CODES = Object.freeze([
|
|
77
|
+
'security-sensitive',
|
|
78
|
+
'shared-impact',
|
|
79
|
+
'public-contract',
|
|
80
|
+
'schema-change',
|
|
81
|
+
'destructive-action',
|
|
82
|
+
'cross-engine',
|
|
83
|
+
'established-precedent',
|
|
84
|
+
'explicit-local-target',
|
|
85
|
+
]);
|
|
86
|
+
const ROUTE_RISK_FLOOR_RAISING_CODES = new Set(ROUTE_RISK_REASON_CODES.slice(0, 6));
|
|
87
|
+
const ROUTE_RISK_ENGINES = ['claude code', 'codex', 'omp'];
|
|
88
|
+
|
|
89
|
+
// FR-004 (M01.3'): Fast Path eligibility vocabulary. The suppressed list is fixed
|
|
90
|
+
// text per SPEC — deliberately not configurable. Reasons are the informational
|
|
91
|
+
// risk codes (the last two ROUTE_RISK_REASON_CODES entries) present on the route.
|
|
92
|
+
const FAST_PATH_MODES = new Set(['tiny-fix', 'local-fix']);
|
|
93
|
+
const FAST_PATH_SUPPRESSED = Object.freeze(['design', 'smart', 'subagents', 'broad-verify']);
|
|
94
|
+
const FAST_PATH_REASON_CODES = new Set(ROUTE_RISK_REASON_CODES.slice(6));
|
|
72
95
|
// 'informational' is a real router emission (no completion contract) even though it is
|
|
73
96
|
// not part of the seven-lane execution-mode ladder.
|
|
74
97
|
export const ROUTE_EXECUTION_MODES = [
|
|
@@ -249,6 +272,162 @@ export function resolveRouteSchemaStage(config = null) {
|
|
|
249
272
|
return ROUTE_SCHEMA_STAGES.has(stage) ? stage : 'off';
|
|
250
273
|
}
|
|
251
274
|
|
|
275
|
+
// FR-002: generic stage resolver — every routing.<key>.stage shares the same
|
|
276
|
+
// absent/malformed → 'off' contract. resolveRouteSchemaStage stays as the
|
|
277
|
+
// routeSchema-specific spelling of this helper.
|
|
278
|
+
export function resolveRouteStage(config = null, key) {
|
|
279
|
+
const stage = config?.routing?.[key]?.stage;
|
|
280
|
+
return ROUTE_SCHEMA_STAGES.has(stage) ? stage : 'off';
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// FR-003 (M01.2'): derive the additive riskFloor from hard signals. Codes are
|
|
284
|
+
// collected in ROUTE_RISK_REASON_CODES table order; the floor is 'high-risk' iff
|
|
285
|
+
// any of the first six (floor-raising) codes fired — informational codes never
|
|
286
|
+
// raise it. Detectors read the normalized signal text (same source the mode
|
|
287
|
+
// ladder uses) plus the raw target path and context preview.
|
|
288
|
+
export function deriveRiskFloor({
|
|
289
|
+
promptText = '',
|
|
290
|
+
commandText = '',
|
|
291
|
+
targetFile = null,
|
|
292
|
+
executionMode = null,
|
|
293
|
+
activeSkillIds = [],
|
|
294
|
+
contextPreview = null,
|
|
295
|
+
} = {}) {
|
|
296
|
+
const signalText = buildNormalizedRouteSignalText(promptText, commandText);
|
|
297
|
+
const target = String(targetFile || '');
|
|
298
|
+
const skillIds = Array.isArray(activeSkillIds) ? activeSkillIds : [];
|
|
299
|
+
const codes = [];
|
|
300
|
+
if (
|
|
301
|
+
/\b(auth|security|token|permission|secret|credential|password|vulnerab|exploit|xss|injection)\b/i.test(signalText)
|
|
302
|
+
|| skillIds.includes('discover-security')
|
|
303
|
+
) {
|
|
304
|
+
codes.push('security-sensitive');
|
|
305
|
+
}
|
|
306
|
+
if (isSharedImpactFile(targetFile) || executionMode === 'shared-edit' || executionMode === 'map-impact') {
|
|
307
|
+
codes.push('shared-impact');
|
|
308
|
+
}
|
|
309
|
+
if (
|
|
310
|
+
/(^|\/)(package\.json|manifests\/|.*\.d\.ts$|(^|\/)api\/|openapi|swagger)/i.test(target)
|
|
311
|
+
|| /\b(public api|breaking change|api contract|semver)\b/i.test(signalText)
|
|
312
|
+
) {
|
|
313
|
+
codes.push('public-contract');
|
|
314
|
+
}
|
|
315
|
+
if (
|
|
316
|
+
/(^|\/)(migrations?|db|database|prisma|schema)/i.test(target)
|
|
317
|
+
|| /\b(migration|migrate|schema|alter table|add column|drop column)\b/i.test(signalText)
|
|
318
|
+
) {
|
|
319
|
+
codes.push('schema-change');
|
|
320
|
+
}
|
|
321
|
+
if (/\b(delete|drop|truncate|destroy|wipe|uninstall|rm -rf|purge)\b/i.test(signalText)) {
|
|
322
|
+
codes.push('destructive-action');
|
|
323
|
+
}
|
|
324
|
+
const engineHits = ROUTE_RISK_ENGINES.filter(
|
|
325
|
+
(name) => new RegExp(`\\b${name}\\b`, 'i').test(signalText),
|
|
326
|
+
).length;
|
|
327
|
+
if (
|
|
328
|
+
/\bcross[- ]engine\b|\ball engines\b/i.test(signalText)
|
|
329
|
+
|| engineHits >= 2
|
|
330
|
+
|| /^template_project\/\.(claude|codex|omp)\//i.test(target)
|
|
331
|
+
) {
|
|
332
|
+
codes.push('cross-engine');
|
|
333
|
+
}
|
|
334
|
+
if ((contextPreview?.analogFiles?.length ?? 0) > 0 || (contextPreview?.styleFiles?.length ?? 0) > 0) {
|
|
335
|
+
codes.push('established-precedent');
|
|
336
|
+
}
|
|
337
|
+
if (target && !isSharedImpactFile(targetFile)) {
|
|
338
|
+
codes.push('explicit-local-target');
|
|
339
|
+
}
|
|
340
|
+
return {
|
|
341
|
+
floor: codes.some((code) => ROUTE_RISK_FLOOR_RAISING_CODES.has(code)) ? 'high-risk' : 'none',
|
|
342
|
+
codes,
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// Route-line segment (FR-003): on 'high-risk' only the floor-raising codes print;
|
|
347
|
+
// on 'none' the informational codes do. Empty list → no segment at all.
|
|
348
|
+
function formatRiskFloorSegment(riskFloor = null) {
|
|
349
|
+
if (!riskFloor) {
|
|
350
|
+
return null;
|
|
351
|
+
}
|
|
352
|
+
const printed = riskFloor.floor === 'high-risk'
|
|
353
|
+
? riskFloor.codes.filter((code) => ROUTE_RISK_FLOOR_RAISING_CODES.has(code))
|
|
354
|
+
: riskFloor.codes;
|
|
355
|
+
return printed.length > 0 ? `risk=${riskFloor.floor}(${printed.join(',')})` : null;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// FR-001 (M01.2' limits fragment): compile the contract's numeric budget keys
|
|
359
|
+
// into an advisory map. Only finite numbers survive — a non-numeric or missing
|
|
360
|
+
// key is simply absent. Zero is a real budget ("no read passes"), never
|
|
361
|
+
// filtered. Same key set as the ceremonyBudget.limits builder below.
|
|
362
|
+
export function deriveCeremonyLimits(executionContract = null) {
|
|
363
|
+
if (executionContract === null || typeof executionContract !== 'object') {
|
|
364
|
+
return {};
|
|
365
|
+
}
|
|
366
|
+
return Object.fromEntries(
|
|
367
|
+
['maxReadPasses', 'maxContextPulls', 'maxReadPassesBeforeReassess']
|
|
368
|
+
.filter((key) => Number.isFinite(executionContract[key]))
|
|
369
|
+
.map((key) => [key, executionContract[key]]),
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// Route-line segment (FR-002): fixed reads,ctx,reassess order; only present
|
|
374
|
+
// keys print. Empty/absent map → null so the segment never appears.
|
|
375
|
+
export function formatLimitsSegment(limits = null) {
|
|
376
|
+
if (limits === null || typeof limits !== 'object') {
|
|
377
|
+
return null;
|
|
378
|
+
}
|
|
379
|
+
const parts = [
|
|
380
|
+
['reads', 'maxReadPasses'],
|
|
381
|
+
['ctx', 'maxContextPulls'],
|
|
382
|
+
['reassess', 'maxReadPassesBeforeReassess'],
|
|
383
|
+
]
|
|
384
|
+
.filter(([, key]) => Number.isFinite(limits[key]))
|
|
385
|
+
.map(([label, key]) => `${label}:${limits[key]}`);
|
|
386
|
+
return parts.length > 0 ? `limits=${parts.join(',')}` : null;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// FR-004 (M01.3'): Fast Path eligibility predicate. Returns null when no riskFloor
|
|
390
|
+
// was supplied — eligibility must never be derived without the floor check, so a
|
|
391
|
+
// missing floor means "not computed", not "none". Eligible iff the lane is
|
|
392
|
+
// tiny-fix/local-fix, exactly one local target is known, the floor is 'none',
|
|
393
|
+
// a bounded verification path exists (targeted commands or the tiny-fix
|
|
394
|
+
// 'minimal-or-targeted' contract policy), and the target is not shared-impact.
|
|
395
|
+
export function deriveFastPath({
|
|
396
|
+
executionMode = null,
|
|
397
|
+
targetFile = null,
|
|
398
|
+
riskFloor = null,
|
|
399
|
+
verificationRecommendation = null,
|
|
400
|
+
contextPreview = null,
|
|
401
|
+
} = {}) {
|
|
402
|
+
if (!riskFloor) {
|
|
403
|
+
return null;
|
|
404
|
+
}
|
|
405
|
+
const reasons = (riskFloor.codes ?? []).filter((code) => FAST_PATH_REASON_CODES.has(code));
|
|
406
|
+
const hasLocalTarget = Boolean(targetFile) || contextPreview?.primaryTargets?.length === 1;
|
|
407
|
+
const hasBoundedVerification = (verificationRecommendation?.commands?.length ?? 0) > 0
|
|
408
|
+
|| buildExecutionContract(executionMode)?.verificationPolicy === 'minimal-or-targeted';
|
|
409
|
+
const eligible = FAST_PATH_MODES.has(executionMode)
|
|
410
|
+
&& hasLocalTarget
|
|
411
|
+
&& riskFloor.floor === 'none'
|
|
412
|
+
&& hasBoundedVerification
|
|
413
|
+
&& !isSharedImpactFile(targetFile);
|
|
414
|
+
return {
|
|
415
|
+
eligible,
|
|
416
|
+
suppressed: eligible ? [...FAST_PATH_SUPPRESSED] : [],
|
|
417
|
+
reasons,
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Route-line segment (FR-004): emitted only for eligible routes — ineligible
|
|
422
|
+
// routes keep the routeSummary.fastPath field for telemetry but stay silent.
|
|
423
|
+
function formatFastPathSegment(fastPath = null) {
|
|
424
|
+
if (!fastPath?.eligible) {
|
|
425
|
+
return null;
|
|
426
|
+
}
|
|
427
|
+
const reasons = fastPath.reasons?.length ? ` (${fastPath.reasons.join(',')})` : '';
|
|
428
|
+
return `fastPath=on | suppress: ${FAST_PATH_SUPPRESSED.join(',')}${reasons}`;
|
|
429
|
+
}
|
|
430
|
+
|
|
252
431
|
// A bare delivery command ("push this to git", "đẩy bộ này lên git") performs no
|
|
253
432
|
// repository mutation the ledger could ever receipt. With no edit/review/debug/build
|
|
254
433
|
// signal present, routing it to an investigation lane fabricates write debt and the
|
|
@@ -311,7 +490,12 @@ function buildResolvedRouteFields({
|
|
|
311
490
|
executionMode = null,
|
|
312
491
|
executionContract = null,
|
|
313
492
|
completionState = null,
|
|
493
|
+
riskFloor = null,
|
|
314
494
|
} = {}) {
|
|
495
|
+
// Decision table v2 (FR-001/FR-002): tier + effort resolve together from the
|
|
496
|
+
// contract lane and the additive riskFloor. The router cannot observe host
|
|
497
|
+
// binding capabilities, so the emitted pair is advisory text by definition.
|
|
498
|
+
const tierDecision = resolveModelTier({ executionMode, riskFloor });
|
|
315
499
|
const signalText = buildNormalizedRouteSignalText(routingContext.promptText, routingContext.commandText);
|
|
316
500
|
const deliveryOnly = isDeliveryOnlyRequest({
|
|
317
501
|
signalText,
|
|
@@ -333,13 +517,15 @@ function buildResolvedRouteFields({
|
|
|
333
517
|
execution: {
|
|
334
518
|
mode: executionMode,
|
|
335
519
|
rigor: null,
|
|
520
|
+
riskFloor: riskFloor?.floor ?? null,
|
|
336
521
|
phase: null,
|
|
337
522
|
contractVersion: ROUTE_CONTRACT_VERSION,
|
|
338
|
-
modelTier:
|
|
523
|
+
modelTier: tierDecision.tier,
|
|
524
|
+
effort: tierDecision.effort,
|
|
339
525
|
},
|
|
340
526
|
evidence: {
|
|
341
527
|
observations: [],
|
|
342
|
-
riskSignals: [],
|
|
528
|
+
riskSignals: riskFloor?.codes ?? [],
|
|
343
529
|
activationReasons: [],
|
|
344
530
|
suppressionReasons: [],
|
|
345
531
|
completionRequirements: unique(completionState?.missingEvidence ?? []),
|
|
@@ -347,7 +533,13 @@ function buildResolvedRouteFields({
|
|
|
347
533
|
ceremonyBudget: {
|
|
348
534
|
policyVersion: ROUTE_CONTRACT_VERSION,
|
|
349
535
|
rigor: null,
|
|
350
|
-
limits:
|
|
536
|
+
limits: riskFloor
|
|
537
|
+
? Object.fromEntries(
|
|
538
|
+
['maxReadPasses', 'maxContextPulls', 'maxReadPassesBeforeReassess']
|
|
539
|
+
.filter((key) => typeof executionContract?.[key] === 'number')
|
|
540
|
+
.map((key) => [key, executionContract[key]]),
|
|
541
|
+
)
|
|
542
|
+
: {},
|
|
351
543
|
consumed: {},
|
|
352
544
|
exceptions: [],
|
|
353
545
|
},
|
|
@@ -403,12 +595,19 @@ export function validateResolvedRoute(route = null) {
|
|
|
403
595
|
if (route.execution.rigor !== null && !ROUTE_RIGOR_LEVELS.has(route.execution.rigor)) {
|
|
404
596
|
errors.push(`execution.rigor must be null or one of: ${[...ROUTE_RIGOR_LEVELS].join(', ')}.`);
|
|
405
597
|
}
|
|
598
|
+
if (route.execution.riskFloor !== null && !ROUTE_RISK_FLOORS.has(route.execution.riskFloor)) {
|
|
599
|
+
errors.push(`execution.riskFloor must be null or one of: ${[...ROUTE_RISK_FLOORS].join(', ')}.`);
|
|
600
|
+
}
|
|
406
601
|
if (route.execution.contractVersion !== ROUTE_CONTRACT_VERSION) {
|
|
407
602
|
errors.push(`execution.contractVersion must be ${ROUTE_CONTRACT_VERSION}.`);
|
|
408
603
|
}
|
|
409
604
|
if (route.execution.modelTier !== null && !ROUTE_MODEL_TIERS.has(route.execution.modelTier)) {
|
|
410
605
|
errors.push(`execution.modelTier must be null or one of: ${[...ROUTE_MODEL_TIERS].join(', ')}.`);
|
|
411
606
|
}
|
|
607
|
+
if (route.execution.effort !== null && route.execution.effort !== undefined
|
|
608
|
+
&& !ROUTE_EFFORTS.has(route.execution.effort)) {
|
|
609
|
+
errors.push(`execution.effort must be null or one of: ${[...ROUTE_EFFORTS].join(', ')}.`);
|
|
610
|
+
}
|
|
412
611
|
}
|
|
413
612
|
if (!isObject(route.evidence)) {
|
|
414
613
|
errors.push('evidence must be an object.');
|
|
@@ -418,6 +617,12 @@ export function validateResolvedRoute(route = null) {
|
|
|
418
617
|
errors.push(`evidence.${key} must be an array.`);
|
|
419
618
|
}
|
|
420
619
|
}
|
|
620
|
+
if (Array.isArray(route.evidence.riskSignals)
|
|
621
|
+
&& route.evidence.riskSignals.some(
|
|
622
|
+
(code) => typeof code !== 'string' || !ROUTE_RISK_REASON_CODES.includes(code),
|
|
623
|
+
)) {
|
|
624
|
+
errors.push(`evidence.riskSignals entries must be one of: ${ROUTE_RISK_REASON_CODES.join(', ')}.`);
|
|
625
|
+
}
|
|
421
626
|
}
|
|
422
627
|
if (!isObject(route.ceremonyBudget)) {
|
|
423
628
|
errors.push('ceremonyBudget must be an object.');
|
|
@@ -1379,11 +1584,24 @@ async function main() {
|
|
|
1379
1584
|
}
|
|
1380
1585
|
: null;
|
|
1381
1586
|
if (rescuedRouteSummary) {
|
|
1587
|
+
// FR-005: the rescued summary IS the previous route state — merge its
|
|
1588
|
+
// persisted riskEscalation with current evidence (monotonic, idempotent).
|
|
1589
|
+
const riskEscalation = computeRiskEscalation({
|
|
1590
|
+
routeSummary: rescuedRouteSummary,
|
|
1591
|
+
previousRouteSummary: cachedRouteState.routeSummary,
|
|
1592
|
+
config: escalationConfig,
|
|
1593
|
+
});
|
|
1594
|
+
if (riskEscalation) {
|
|
1595
|
+
rescuedRouteSummary.riskEscalation = riskEscalation;
|
|
1596
|
+
} else {
|
|
1597
|
+
delete rescuedRouteSummary.riskEscalation;
|
|
1598
|
+
}
|
|
1382
1599
|
applyRescueBiasToRouteSummary(rescuedRouteSummary);
|
|
1383
1600
|
applyEscalationToRouteSummary(rescuedRouteSummary, {
|
|
1384
1601
|
config: escalationConfig,
|
|
1385
1602
|
targetFile: cachedRouteState.routingContext?.targetFile ?? null,
|
|
1386
1603
|
});
|
|
1604
|
+
appendRiskEscalationSegment(rescuedRouteSummary);
|
|
1387
1605
|
}
|
|
1388
1606
|
const sharedState = {
|
|
1389
1607
|
...cachedRouteState,
|
|
@@ -1673,11 +1891,25 @@ async function finalizeTaskRoute({
|
|
|
1673
1891
|
previousRouteSummary?.continuationState ?? null,
|
|
1674
1892
|
resolveEscalationSettings(escalationConfig),
|
|
1675
1893
|
);
|
|
1894
|
+
// FR-005: merge risk evidence with the persisted previous riskEscalation AFTER
|
|
1895
|
+
// advanceContinuationState (stuckRisk is already advanced). Stage 'off'
|
|
1896
|
+
// returns null → the field is dropped, not carried forward.
|
|
1897
|
+
const riskEscalation = computeRiskEscalation({
|
|
1898
|
+
routeSummary,
|
|
1899
|
+
previousRouteSummary,
|
|
1900
|
+
config: escalationConfig,
|
|
1901
|
+
});
|
|
1902
|
+
if (riskEscalation) {
|
|
1903
|
+
routeSummary.riskEscalation = riskEscalation;
|
|
1904
|
+
} else {
|
|
1905
|
+
delete routeSummary.riskEscalation;
|
|
1906
|
+
}
|
|
1676
1907
|
applyRescueBiasToRouteSummary(routeSummary);
|
|
1677
1908
|
applyEscalationToRouteSummary(routeSummary, {
|
|
1678
1909
|
config: escalationConfig,
|
|
1679
1910
|
targetFile: routingContext.targetFile ?? null,
|
|
1680
1911
|
});
|
|
1912
|
+
appendRiskEscalationSegment(routeSummary);
|
|
1681
1913
|
const approachSelector = routeSummary?.approachSelector ?? null;
|
|
1682
1914
|
|
|
1683
1915
|
return {
|
|
@@ -2672,6 +2904,48 @@ function buildRouteSummary({
|
|
|
2672
2904
|
nextActionType: nextAction?.type ?? null,
|
|
2673
2905
|
completionState,
|
|
2674
2906
|
});
|
|
2907
|
+
// FR-003 (M01.2'): riskFloor is a top-level additive field emitted whenever ANY
|
|
2908
|
+
// of rigor/fastPath/escalation stages is on — fastPath/escalation consumers read
|
|
2909
|
+
// it even when routeSchema is off. All three off → absent, byte-identical route.
|
|
2910
|
+
const riskStageOn = ['rigor', 'fastPath', 'escalation']
|
|
2911
|
+
.some((key) => resolveRouteStage(runtimeConfig, key) !== 'off');
|
|
2912
|
+
const riskFloor = riskStageOn
|
|
2913
|
+
? deriveRiskFloor({
|
|
2914
|
+
promptText: routingContext.promptText,
|
|
2915
|
+
commandText: routingContext.commandText,
|
|
2916
|
+
targetFile: routingContext.targetFile ?? null,
|
|
2917
|
+
executionMode,
|
|
2918
|
+
activeSkillIds: activeSkills.map((entry) => entry.id),
|
|
2919
|
+
contextPreview: contextRecommendation?.preview ?? null,
|
|
2920
|
+
})
|
|
2921
|
+
: null;
|
|
2922
|
+
const riskSegment = formatRiskFloorSegment(riskFloor);
|
|
2923
|
+
// FR-003 (M01.2' limits fragment): the rigor advisory — emitted whenever
|
|
2924
|
+
// rigor.stage is on, independent of fastPath/escalation. Stage off → no
|
|
2925
|
+
// segment, byte-identical route.
|
|
2926
|
+
const limitsSegment = resolveRouteStage(runtimeConfig, 'rigor') !== 'off'
|
|
2927
|
+
? formatLimitsSegment(deriveCeremonyLimits(executionContract))
|
|
2928
|
+
: null;
|
|
2929
|
+
// FR-004 (M01.3'): fastPath is emitted whenever its own stage is on — the field
|
|
2930
|
+
// is always set then (eligible or not) so telemetry/harness can read it; the
|
|
2931
|
+
// route-line segment prints only for eligible routes.
|
|
2932
|
+
const fastPathStage = resolveRouteStage(runtimeConfig, 'fastPath');
|
|
2933
|
+
const fastPath = fastPathStage !== 'off'
|
|
2934
|
+
? {
|
|
2935
|
+
eligible: false,
|
|
2936
|
+
suppressed: [],
|
|
2937
|
+
reasons: [],
|
|
2938
|
+
...deriveFastPath({
|
|
2939
|
+
executionMode,
|
|
2940
|
+
targetFile: routingContext.targetFile ?? null,
|
|
2941
|
+
riskFloor,
|
|
2942
|
+
verificationRecommendation,
|
|
2943
|
+
contextPreview: contextRecommendation?.preview ?? null,
|
|
2944
|
+
}),
|
|
2945
|
+
stage: fastPathStage,
|
|
2946
|
+
}
|
|
2947
|
+
: null;
|
|
2948
|
+
const fastPathSegment = formatFastPathSegment(fastPath);
|
|
2675
2949
|
const resolvedRouteFields = routeSchemaStage !== 'off'
|
|
2676
2950
|
? buildResolvedRouteFields({
|
|
2677
2951
|
routingContext,
|
|
@@ -2679,6 +2953,7 @@ function buildRouteSummary({
|
|
|
2679
2953
|
executionMode,
|
|
2680
2954
|
executionContract,
|
|
2681
2955
|
completionState,
|
|
2956
|
+
riskFloor,
|
|
2682
2957
|
})
|
|
2683
2958
|
: null;
|
|
2684
2959
|
const helperHint = compactHelperHint(
|
|
@@ -2722,6 +2997,9 @@ function buildRouteSummary({
|
|
|
2722
2997
|
formatCompactSegment('tests', relatedTests),
|
|
2723
2998
|
formatCompactSegment('styles', styleFiles),
|
|
2724
2999
|
editGuardHint ? `editGuard=${editGuardHint}` : null,
|
|
3000
|
+
riskSegment,
|
|
3001
|
+
limitsSegment,
|
|
3002
|
+
fastPathSegment,
|
|
2725
3003
|
delegationRecommendation?.hint ? `delegate=${delegationRecommendation.hint}` : null,
|
|
2726
3004
|
policyMode ? `policy=${policyMode}` : null,
|
|
2727
3005
|
workflowPolicyName ? `workflow=${workflowPolicyName}` : null,
|
|
@@ -2742,6 +3020,10 @@ function buildRouteSummary({
|
|
|
2742
3020
|
completionState,
|
|
2743
3021
|
// M01.1 additive C01 groups — present only when routing.routeSchema.stage != "off".
|
|
2744
3022
|
...(resolvedRouteFields ?? {}),
|
|
3023
|
+
// FR-003 additive top-level field — present only when a risk stage is on.
|
|
3024
|
+
...(riskFloor ? { riskFloor } : {}),
|
|
3025
|
+
// FR-004 additive top-level field — present only when fastPath stage is on.
|
|
3026
|
+
...(fastPath ? { fastPath } : {}),
|
|
2745
3027
|
continuationState,
|
|
2746
3028
|
autonomyLevel,
|
|
2747
3029
|
continuousExecution,
|
|
@@ -3208,6 +3490,45 @@ function buildExecutionContract(executionMode = null) {
|
|
|
3208
3490
|
return contracts[executionMode] ? { ...contracts[executionMode] } : null;
|
|
3209
3491
|
}
|
|
3210
3492
|
|
|
3493
|
+
// Decision table v2 (V3_RESHAPE §5): the contracts table's modelTier column is the
|
|
3494
|
+
// base row; resolveModelTier adds the (riskFloor, hostCapabilities) columns.
|
|
3495
|
+
// Deterministic — no registry, no leases, no outbound capability calls.
|
|
3496
|
+
// Literal mirror of src/core/executionContracts.js resolveModelTier; parity is
|
|
3497
|
+
// locked by tests/consistency/executionContractSync.test.js.
|
|
3498
|
+
const MODEL_TIER_ORDER = ['lite', 'code', 'smart'];
|
|
3499
|
+
const MODEL_TIER_EFFORT = {
|
|
3500
|
+
lite: 'low',
|
|
3501
|
+
code: 'medium',
|
|
3502
|
+
smart: 'high',
|
|
3503
|
+
};
|
|
3504
|
+
|
|
3505
|
+
/**
|
|
3506
|
+
* Resolves {tier, effort, advisoryOnly} for a route. A 'high-risk' floor escalates
|
|
3507
|
+
* the tier one band (lite→code→smart, capped at smart) and forces effort 'high'.
|
|
3508
|
+
* Unknown mode → {tier:null, effort:null, advisoryOnly:true}. Missing/unknown
|
|
3509
|
+
* riskFloor → 'none'. Missing hostCapabilities → advisoryOnly:true (the route text
|
|
3510
|
+
* is all the host gets when it cannot bind model and effort).
|
|
3511
|
+
*/
|
|
3512
|
+
export function resolveModelTier({
|
|
3513
|
+
executionMode = null,
|
|
3514
|
+
riskFloor = null,
|
|
3515
|
+
hostCapabilities = null,
|
|
3516
|
+
} = {}) {
|
|
3517
|
+
const baseTier = buildExecutionContract(executionMode)?.modelTier ?? null;
|
|
3518
|
+
if (!baseTier) {
|
|
3519
|
+
return { tier: null, effort: null, advisoryOnly: true };
|
|
3520
|
+
}
|
|
3521
|
+
const highRisk = riskFloor?.floor === 'high-risk';
|
|
3522
|
+
const tier = highRisk
|
|
3523
|
+
? MODEL_TIER_ORDER[Math.min(MODEL_TIER_ORDER.indexOf(baseTier) + 1, MODEL_TIER_ORDER.length - 1)]
|
|
3524
|
+
: baseTier;
|
|
3525
|
+
return {
|
|
3526
|
+
tier,
|
|
3527
|
+
effort: highRisk ? 'high' : MODEL_TIER_EFFORT[tier],
|
|
3528
|
+
advisoryOnly: !(hostCapabilities?.canBindModel === true && hostCapabilities?.canBindEffort === true),
|
|
3529
|
+
};
|
|
3530
|
+
}
|
|
3531
|
+
|
|
3211
3532
|
function buildApproachSelectorResult({
|
|
3212
3533
|
executionMode = null,
|
|
3213
3534
|
executionScores = null,
|
|
@@ -3403,18 +3724,24 @@ function resolveEscalationSettings(config = null) {
|
|
|
3403
3724
|
* Escalates exactly one rung above `modelTier` on `tierOrder`, capped at `cap`. Returns null when
|
|
3404
3725
|
* escalation is disabled, `repeatCount` hasn't reached `debugLoopThreshold`, or `modelTier` isn't
|
|
3405
3726
|
* on the cost ladder (e.g. no contract selected). Never returns 'vision'.
|
|
3727
|
+
* FR-005: when `riskEscalation.level === 'high'` the repeat-count threshold is treated as
|
|
3728
|
+
* satisfied (immediate one-rung escalation) and the effective cap rises to 'smart', overriding
|
|
3729
|
+
* the configured cap; the reason is prefixed `risk-floor:` so consumers can tell risk-driven
|
|
3730
|
+
* escalation from repeat-count escalation.
|
|
3406
3731
|
*/
|
|
3407
3732
|
function computeEscalation({
|
|
3408
3733
|
modelTier = null,
|
|
3409
3734
|
repeatCount = null,
|
|
3410
3735
|
config = null,
|
|
3411
3736
|
targetFile = null,
|
|
3737
|
+
riskEscalation = null,
|
|
3412
3738
|
} = {}) {
|
|
3413
|
-
if (!modelTier
|
|
3739
|
+
if (!modelTier) {
|
|
3414
3740
|
return null;
|
|
3415
3741
|
}
|
|
3416
3742
|
const settings = resolveEscalationSettings(config);
|
|
3417
|
-
|
|
3743
|
+
const riskDriven = riskEscalation?.level === 'high';
|
|
3744
|
+
if (!settings.enabled || (!riskDriven && (!Number.isFinite(repeatCount) || repeatCount < settings.debugLoopThreshold))) {
|
|
3418
3745
|
return null;
|
|
3419
3746
|
}
|
|
3420
3747
|
const currentIndex = settings.tierOrder.indexOf(modelTier);
|
|
@@ -3422,18 +3749,23 @@ function computeEscalation({
|
|
|
3422
3749
|
return null;
|
|
3423
3750
|
}
|
|
3424
3751
|
const capIndex = settings.tierOrder.indexOf(settings.cap);
|
|
3425
|
-
const
|
|
3752
|
+
const smartIndex = settings.tierOrder.indexOf('smart');
|
|
3753
|
+
const effectiveCapIndex = riskDriven
|
|
3754
|
+
? (smartIndex === -1 ? settings.tierOrder.length - 1 : smartIndex)
|
|
3755
|
+
: (capIndex === -1 ? settings.tierOrder.length - 1 : capIndex);
|
|
3426
3756
|
const escalatedIndex = Math.min(currentIndex + 1, effectiveCapIndex);
|
|
3427
3757
|
const escalatedTier = settings.tierOrder[escalatedIndex];
|
|
3428
3758
|
|
|
3429
3759
|
return {
|
|
3430
3760
|
escalatedTier,
|
|
3431
|
-
escalationReason:
|
|
3761
|
+
escalationReason: riskDriven
|
|
3762
|
+
? `risk-floor: level=${riskEscalation.level} sources=${(riskEscalation.sources ?? []).join(',')} file=${targetFile ?? 'null'}`
|
|
3763
|
+
: `repeat-count=${repeatCount} threshold=${settings.debugLoopThreshold} file=${targetFile ?? 'null'}`,
|
|
3432
3764
|
};
|
|
3433
3765
|
}
|
|
3434
3766
|
|
|
3435
3767
|
/** Attaches escalatedTier/escalationReason to routeSummary, additive alongside modelTier. */
|
|
3436
|
-
function applyEscalationToRouteSummary(routeSummary = null, { config = null, targetFile = null } = {}) {
|
|
3768
|
+
export function applyEscalationToRouteSummary(routeSummary = null, { config = null, targetFile = null } = {}) {
|
|
3437
3769
|
if (!routeSummary || typeof routeSummary !== 'object') {
|
|
3438
3770
|
return routeSummary;
|
|
3439
3771
|
}
|
|
@@ -3443,6 +3775,7 @@ function applyEscalationToRouteSummary(routeSummary = null, { config = null, tar
|
|
|
3443
3775
|
repeatCount: routeSummary.continuationState?.repeatCount ?? null,
|
|
3444
3776
|
config,
|
|
3445
3777
|
targetFile,
|
|
3778
|
+
riskEscalation: routeSummary.riskEscalation ?? null,
|
|
3446
3779
|
});
|
|
3447
3780
|
|
|
3448
3781
|
if (escalation) {
|
|
@@ -3462,6 +3795,65 @@ function applyEscalationToRouteSummary(routeSummary = null, { config = null, tar
|
|
|
3462
3795
|
return routeSummary;
|
|
3463
3796
|
}
|
|
3464
3797
|
|
|
3798
|
+
// FR-005 (M01.4'): monotonic risk-evidence escalation. Sources are `risk-floor`
|
|
3799
|
+
// (routeSummary.riskFloor.floor === 'high-risk') and `stuck-risk`
|
|
3800
|
+
// (routeSummary.continuationState.stuckRisk === 'high' — read off the CURRENT
|
|
3801
|
+
// summary, which finalizeTaskRoute has already advanced). Sources merge as the
|
|
3802
|
+
// sorted union of current evidence and the persisted previous
|
|
3803
|
+
// riskEscalation.sources, so replaying the same evidence is a no-op and the
|
|
3804
|
+
// level can never decrease within a run (none < elevated < high). Stage 'off'
|
|
3805
|
+
// returns null unconditionally — a mid-run stage flip drops the field entirely
|
|
3806
|
+
// so the Stop gate sees nothing and the stage-off byte-identity contract holds.
|
|
3807
|
+
// Per-source flags: routing.escalation.sources.<source>: false disables that
|
|
3808
|
+
// source's current detection (absent = all sources on).
|
|
3809
|
+
const RISK_ESCALATION_LEVELS = { none: 0, elevated: 1, high: 2 };
|
|
3810
|
+
|
|
3811
|
+
export function computeRiskEscalation({
|
|
3812
|
+
routeSummary = null,
|
|
3813
|
+
previousRouteSummary = null,
|
|
3814
|
+
config = null,
|
|
3815
|
+
} = {}) {
|
|
3816
|
+
const stage = resolveRouteStage(config, 'escalation');
|
|
3817
|
+
if (stage === 'off') {
|
|
3818
|
+
return null;
|
|
3819
|
+
}
|
|
3820
|
+
const sourceFlags = config?.routing?.escalation?.sources ?? {};
|
|
3821
|
+
const isSourceEnabled = (source) => sourceFlags[source] !== false;
|
|
3822
|
+
const currentSources = [];
|
|
3823
|
+
if (isSourceEnabled('risk-floor') && routeSummary?.riskFloor?.floor === 'high-risk') {
|
|
3824
|
+
currentSources.push('risk-floor');
|
|
3825
|
+
}
|
|
3826
|
+
if (isSourceEnabled('stuck-risk') && routeSummary?.continuationState?.stuckRisk === 'high') {
|
|
3827
|
+
currentSources.push('stuck-risk');
|
|
3828
|
+
}
|
|
3829
|
+
const previous = previousRouteSummary?.riskEscalation ?? null;
|
|
3830
|
+
const sources = unique([...(previous?.sources ?? []), ...currentSources]).sort();
|
|
3831
|
+
const derivedLevel = sources.some((source) => source === 'risk-floor' || source === 'stuck-risk')
|
|
3832
|
+
? 'high'
|
|
3833
|
+
: (sources.length > 0 ? 'elevated' : 'none');
|
|
3834
|
+
const previousLevel = RISK_ESCALATION_LEVELS[previous?.level] ?? 0;
|
|
3835
|
+
const level = RISK_ESCALATION_LEVELS[derivedLevel] >= previousLevel
|
|
3836
|
+
? derivedLevel
|
|
3837
|
+
: previous.level;
|
|
3838
|
+
return { level, sources, stage };
|
|
3839
|
+
}
|
|
3840
|
+
|
|
3841
|
+
// FR-005: buildRouteSummary runs before riskEscalation exists, so the
|
|
3842
|
+
// `escalate=<level>(<sources>)` segment is appended here, where the merge
|
|
3843
|
+
// happens. Any previously emitted segment is stripped first — replay on a
|
|
3844
|
+
// rescued compacted summary must not double-append (idempotent).
|
|
3845
|
+
function appendRiskEscalationSegment(routeSummary = null) {
|
|
3846
|
+
if (!routeSummary || typeof routeSummary.line !== 'string') {
|
|
3847
|
+
return routeSummary;
|
|
3848
|
+
}
|
|
3849
|
+
const baseLine = routeSummary.line.replace(/(?: \| )?escalate=\S+$/, '');
|
|
3850
|
+
const riskEscalation = routeSummary.riskEscalation;
|
|
3851
|
+
routeSummary.line = riskEscalation && riskEscalation.level !== 'none'
|
|
3852
|
+
? `${baseLine} | escalate=${riskEscalation.level}(${(riskEscalation.sources ?? []).join(',')})`
|
|
3853
|
+
: baseLine;
|
|
3854
|
+
return routeSummary;
|
|
3855
|
+
}
|
|
3856
|
+
|
|
3465
3857
|
// WS-E tier-role wiring: a contract tier only takes effect when the executing session hands
|
|
3466
3858
|
// the work to an agent whose definition binds that tier — otherwise every session behaves as
|
|
3467
3859
|
// if it only had one model. `code` is the DEFAULT implementation lane, so a code-tier contract
|
|
@@ -3690,10 +4082,10 @@ const SHARED_IMPACT_PATTERNS = [
|
|
|
3690
4082
|
/^src\/index\//,
|
|
3691
4083
|
/^src\/core\/(runInstallPipeline|applyPlan|buildPlan|diffPlan|metadata|migrateLegacy|uninstall|runtimeConfig|runtimePaths)\.js$/,
|
|
3692
4084
|
/^src\/core\/(output|token|compact)\//,
|
|
3693
|
-
/^
|
|
3694
|
-
/^
|
|
4085
|
+
/^template_project\/\.claude\/hooks\//,
|
|
4086
|
+
/^template_project\/\.claude\/ukit\//,
|
|
3695
4087
|
/^manifests\/platform\.full\.yaml$/,
|
|
3696
|
-
/^
|
|
4088
|
+
/^template_project\//,
|
|
3697
4089
|
];
|
|
3698
4090
|
|
|
3699
4091
|
function isSharedImpactFile(filePath) {
|
|
@@ -4179,7 +4571,7 @@ function compactRecentOutput(recentOutput = null) {
|
|
|
4179
4571
|
};
|
|
4180
4572
|
}
|
|
4181
4573
|
|
|
4182
|
-
function compactRouteSummary(routeSummary = null) {
|
|
4574
|
+
export function compactRouteSummary(routeSummary = null) {
|
|
4183
4575
|
if (!routeSummary) {
|
|
4184
4576
|
return null;
|
|
4185
4577
|
}
|
|
@@ -4221,6 +4613,10 @@ function compactRouteSummary(routeSummary = null) {
|
|
|
4221
4613
|
escalatedTier: routeSummary.escalatedTier,
|
|
4222
4614
|
escalationReason: routeSummary.escalationReason ?? null,
|
|
4223
4615
|
} : {}),
|
|
4616
|
+
// FR-005: riskEscalation is the Stop-gate carrier (FR-006) — it must survive
|
|
4617
|
+
// skill-router-state.json compaction. Conditional spread keeps stage-off
|
|
4618
|
+
// output byte-identical (no key emitted when the field is absent).
|
|
4619
|
+
...(routeSummary.riskEscalation ? { riskEscalation: routeSummary.riskEscalation } : {}),
|
|
4224
4620
|
// M01.1 compact whitelist (C01): grouped fields survive compaction minus verbose
|
|
4225
4621
|
// evidence; absent entirely when the route schema stage is off.
|
|
4226
4622
|
...(compactResolvedRoute(routeSummary) ?? {}),
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
* Fail-safe direction (do not re-flip this): `unicMode` keeps BINARY semantics on every runtime
|
|
36
36
|
* — `unicMode = sources.length > 0`, default `false`. Inconclusive detection never resolves to
|
|
37
37
|
* `true`. The "assume UNIC when ambiguous" fail-safe some tools want belongs ONLY to the static
|
|
38
|
-
* `modelRoles` values TASK-003 writes unconditionally into `
|
|
38
|
+
* `modelRoles` values TASK-003 writes unconditionally into `template_project/.omp/config.yml`
|
|
39
39
|
* (`@vision: unic-vision`, no probe involved) — never to this module's boolean, because this
|
|
40
40
|
* module is shared by every runtime and flipping its default would make Codex/Kilo/OPENAI_BASE_URL
|
|
41
41
|
* sessions with zero omp/Claude signal start false-positively reporting UNIC mode.
|
|
@@ -1588,7 +1588,7 @@ export async function recordExecutionReceipt({
|
|
|
1588
1588
|
}
|
|
1589
1589
|
|
|
1590
1590
|
// F-15: mirror of isExplicitBroadVerificationRequest in
|
|
1591
|
-
//
|
|
1591
|
+
// template_project/.claude/hooks/verification-guard.sh — the guard uses this prompt signal to
|
|
1592
1592
|
// let a broad suite run under a targeted policy, so the completion gate must honor the
|
|
1593
1593
|
// same signal when it classifies the resulting broad receipt. Keep both lists in sync.
|
|
1594
1594
|
function isExplicitBroadVerificationRequest(promptText) {
|
|
@@ -1628,10 +1628,19 @@ function explicitBroadVerificationRequested(state = {}) {
|
|
|
1628
1628
|
function requiredEvidence(state = {}) {
|
|
1629
1629
|
const routeSummary = state?.routeSummary || {};
|
|
1630
1630
|
const contractEvidence = routeSummary.executionContract?.completionEvidence;
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1631
|
+
const required = Array.isArray(contractEvidence) && contractEvidence.length > 0
|
|
1632
|
+
? [...contractEvidence]
|
|
1633
|
+
: [...(routeSummary.completionState?.missingEvidence || [])];
|
|
1634
|
+
// FR-006 (M01.4' tail): a route persisted with a high riskEscalation must re-verify at
|
|
1635
|
+
// Stop even when its own contract only demands write evidence. The route state is the
|
|
1636
|
+
// carrier — no config read here; absent/malformed/non-high fields are a no-op.
|
|
1637
|
+
// C48 FR-004: a record stamped `stage: 'shadow'` is advisory-only and does not demand
|
|
1638
|
+
// verification-evidence; a missing or malformed stage fails closed (enforcing) so
|
|
1639
|
+
// pre-C48 persisted records keep re-verifying until re-stamped.
|
|
1640
|
+
if (routeSummary.riskEscalation?.level === 'high' && routeSummary.riskEscalation?.stage !== 'shadow') {
|
|
1641
|
+
required.push('verification-evidence');
|
|
1642
|
+
}
|
|
1643
|
+
return [...new Set(required)];
|
|
1635
1644
|
}
|
|
1636
1645
|
|
|
1637
1646
|
function evidenceSatisfied(evidence, ledger = {}, state = {}, { cwd } = {}) {
|
|
@@ -27,15 +27,15 @@ const SHARED_RISK_PATTERNS = [
|
|
|
27
27
|
/^\.claude\/hooks\//,
|
|
28
28
|
/^\.claude\/ukit\//,
|
|
29
29
|
/^\.codex\//,
|
|
30
|
-
/^
|
|
31
|
-
/^
|
|
30
|
+
/^template_project\/\.claude\/hooks\//,
|
|
31
|
+
/^template_project\/\.claude\/ukit\//,
|
|
32
32
|
/^src\/index\//,
|
|
33
33
|
/^src\/core\/(runInstallPipeline|applyPlan|buildPlan|diffPlan|metadata|migrateLegacy|uninstall|runtimeConfig|runtimePaths)\.js$/,
|
|
34
34
|
/^src\/core\/(output|token|compact)\//,
|
|
35
35
|
/^manifests\/platform\.full\.yaml$/,
|
|
36
36
|
// Intentional for UKit development: template edits become installed runtime behavior after `ukit install`,
|
|
37
37
|
// so templates stay in the strict shared-risk lane rather than being treated as ordinary docs/assets.
|
|
38
|
-
/^
|
|
38
|
+
/^template_project\//,
|
|
39
39
|
/^scripts\//,
|
|
40
40
|
/(^|\/)(AGENTS|CLAUDE)\.md$/,
|
|
41
41
|
];
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Installed-runtime mirror of src/core/sensitiveValueScanner.js — the
|
|
5
5
|
* high-confidence secret *value* scanner shared with
|
|
6
|
-
*
|
|
6
|
+
* template_project/.claude/hooks/sensitive-data-guard.sh. Deliberate mirror: the
|
|
7
7
|
* installed runtime cannot import package source, so this file is kept
|
|
8
8
|
* byte-semantic with the source module and locked by
|
|
9
9
|
* tests/consistency/projectImportantRuntimeParity.test.js.
|