@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
package/src/index/taskRouting.js
CHANGED
|
@@ -11,6 +11,8 @@ import {
|
|
|
11
11
|
EXECUTION_CONTRACTS,
|
|
12
12
|
EXECUTION_MODE_ORDER,
|
|
13
13
|
MODEL_TIER_BY_CONTRACT,
|
|
14
|
+
ROUTE_EFFORTS,
|
|
15
|
+
resolveModelTier,
|
|
14
16
|
} from '../core/executionContracts.js';
|
|
15
17
|
import { resolveModelRoles, readMergedRuntimeConfig } from '../core/runtimeConfig.js';
|
|
16
18
|
import { resolvePlaybook } from '../core/userPlaybooks.js';
|
|
@@ -18,7 +20,7 @@ import { resolvePlaybook } from '../core/userPlaybooks.js';
|
|
|
18
20
|
// --- v3 route-side advisory blocks (docs/pstack/SPEC-playbook-todo.md, ------------------
|
|
19
21
|
// SPEC-principle-index.md, SPEC-model-roles.md). All three are additive stdout text —
|
|
20
22
|
// they never change mode selection. Static text is byte-stable for prompt-cache reuse.
|
|
21
|
-
// Mirrored literally in
|
|
23
|
+
// Mirrored literally in template_project/.claude/ukit/index/route-task.mjs (parity-locked by
|
|
22
24
|
// tests/consistency/executionContractSync.test.js).
|
|
23
25
|
|
|
24
26
|
// SPEC-playbook-todo §2.1: numbered step lists the model copies verbatim into its todo
|
|
@@ -155,6 +157,29 @@ export const ROUTE_INTENT_KINDS = new Set(['informational', 'delivery', 'mutatio
|
|
|
155
157
|
export const ROUTE_MUTABILITIES = new Set(['read-only', 'mutating', 'mixed']);
|
|
156
158
|
export const ROUTE_RIGOR_LEVELS = new Set(['R0', 'R1', 'R2', 'R3', 'R4']);
|
|
157
159
|
export const ROUTE_MODEL_TIERS = new Set(['lite', 'code', 'smart']);
|
|
160
|
+
export const ROUTE_RISK_FLOORS = new Set(['none', 'high-risk']);
|
|
161
|
+
// SPEC §5 FR-003: fixed table order — codes are emitted and printed in this order.
|
|
162
|
+
// The first six raise the floor to 'high-risk'; the last two are informational only.
|
|
163
|
+
export const ROUTE_RISK_REASON_CODES = Object.freeze([
|
|
164
|
+
'security-sensitive',
|
|
165
|
+
'shared-impact',
|
|
166
|
+
'public-contract',
|
|
167
|
+
'schema-change',
|
|
168
|
+
'destructive-action',
|
|
169
|
+
'cross-engine',
|
|
170
|
+
'established-precedent',
|
|
171
|
+
'explicit-local-target',
|
|
172
|
+
]);
|
|
173
|
+
const ROUTE_RISK_FLOOR_RAISING_CODES = new Set(ROUTE_RISK_REASON_CODES.slice(0, 6));
|
|
174
|
+
const ROUTE_RISK_ENGINES = ['claude code', 'codex', 'omp'];
|
|
175
|
+
|
|
176
|
+
// FR-004 (M01.3'): Fast Path eligibility vocabulary. The suppressed list is fixed
|
|
177
|
+
// text per SPEC — deliberately not configurable. Reasons are the informational
|
|
178
|
+
// risk codes (the last two ROUTE_RISK_REASON_CODES entries) present on the route.
|
|
179
|
+
const FAST_PATH_MODES = new Set(['tiny-fix', 'local-fix']);
|
|
180
|
+
const FAST_PATH_SUPPRESSED = Object.freeze(['design', 'smart', 'subagents', 'broad-verify']);
|
|
181
|
+
const FAST_PATH_REASON_CODES = new Set(ROUTE_RISK_REASON_CODES.slice(6));
|
|
182
|
+
|
|
158
183
|
// 'informational' is a real router emission (no completion contract) even though it is
|
|
159
184
|
// not part of the seven-lane EXECUTION_MODE_ORDER ladder.
|
|
160
185
|
export const ROUTE_EXECUTION_MODES = [...EXECUTION_MODE_ORDER, 'informational'];
|
|
@@ -169,6 +194,163 @@ export function resolveRouteSchemaStage(config = null) {
|
|
|
169
194
|
return ROUTE_SCHEMA_STAGES.has(stage) ? stage : 'off';
|
|
170
195
|
}
|
|
171
196
|
|
|
197
|
+
// FR-002: generic stage resolver — every routing.<key>.stage shares the same
|
|
198
|
+
// absent/malformed → 'off' contract. resolveRouteSchemaStage stays as the
|
|
199
|
+
// routeSchema-specific spelling of this helper.
|
|
200
|
+
export function resolveRouteStage(config = null, key) {
|
|
201
|
+
const stage = config?.routing?.[key]?.stage;
|
|
202
|
+
return ROUTE_SCHEMA_STAGES.has(stage) ? stage : 'off';
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// FR-003 (M01.2'): derive the additive riskFloor from hard signals. Codes are
|
|
206
|
+
// collected in ROUTE_RISK_REASON_CODES table order; the floor is 'high-risk' iff
|
|
207
|
+
// any of the first six (floor-raising) codes fired — informational codes never
|
|
208
|
+
// raise it. Detectors read the normalized signal text (same source the mode
|
|
209
|
+
// ladder uses) plus the raw target path and context preview.
|
|
210
|
+
export function deriveRiskFloor({
|
|
211
|
+
promptText = '',
|
|
212
|
+
commandText = '',
|
|
213
|
+
targetFile = null,
|
|
214
|
+
executionMode = null,
|
|
215
|
+
activeSkillIds = [],
|
|
216
|
+
contextPreview = null,
|
|
217
|
+
} = {}) {
|
|
218
|
+
const signalText = buildRouteSignalText(promptText, commandText);
|
|
219
|
+
const target = String(targetFile || '');
|
|
220
|
+
const skillIds = Array.isArray(activeSkillIds) ? activeSkillIds : [];
|
|
221
|
+
const codes = [];
|
|
222
|
+
if (
|
|
223
|
+
/\b(auth|security|token|permission|secret|credential|password|vulnerab|exploit|xss|injection)\b/i.test(signalText)
|
|
224
|
+
|| skillIds.includes('discover-security')
|
|
225
|
+
) {
|
|
226
|
+
codes.push('security-sensitive');
|
|
227
|
+
}
|
|
228
|
+
if (isSharedImpactFile(targetFile) || executionMode === 'shared-edit' || executionMode === 'map-impact') {
|
|
229
|
+
codes.push('shared-impact');
|
|
230
|
+
}
|
|
231
|
+
if (
|
|
232
|
+
/(^|\/)(package\.json|manifests\/|.*\.d\.ts$|(^|\/)api\/|openapi|swagger)/i.test(target)
|
|
233
|
+
|| /\b(public api|breaking change|api contract|semver)\b/i.test(signalText)
|
|
234
|
+
) {
|
|
235
|
+
codes.push('public-contract');
|
|
236
|
+
}
|
|
237
|
+
if (
|
|
238
|
+
/(^|\/)(migrations?|db|database|prisma|schema)/i.test(target)
|
|
239
|
+
|| /\b(migration|migrate|schema|alter table|add column|drop column)\b/i.test(signalText)
|
|
240
|
+
) {
|
|
241
|
+
codes.push('schema-change');
|
|
242
|
+
}
|
|
243
|
+
if (/\b(delete|drop|truncate|destroy|wipe|uninstall|rm -rf|purge)\b/i.test(signalText)) {
|
|
244
|
+
codes.push('destructive-action');
|
|
245
|
+
}
|
|
246
|
+
const engineHits = ROUTE_RISK_ENGINES.filter(
|
|
247
|
+
(name) => new RegExp(`\\b${name}\\b`, 'i').test(signalText),
|
|
248
|
+
).length;
|
|
249
|
+
if (
|
|
250
|
+
/\bcross[- ]engine\b|\ball engines\b/i.test(signalText)
|
|
251
|
+
|| engineHits >= 2
|
|
252
|
+
|| /^template_project\/\.(claude|codex|omp)\//i.test(target)
|
|
253
|
+
) {
|
|
254
|
+
codes.push('cross-engine');
|
|
255
|
+
}
|
|
256
|
+
if ((contextPreview?.analogFiles?.length ?? 0) > 0 || (contextPreview?.styleFiles?.length ?? 0) > 0) {
|
|
257
|
+
codes.push('established-precedent');
|
|
258
|
+
}
|
|
259
|
+
if (target && !isSharedImpactFile(targetFile)) {
|
|
260
|
+
codes.push('explicit-local-target');
|
|
261
|
+
}
|
|
262
|
+
return {
|
|
263
|
+
floor: codes.some((code) => ROUTE_RISK_FLOOR_RAISING_CODES.has(code)) ? 'high-risk' : 'none',
|
|
264
|
+
codes,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Route-line segment (FR-003): on 'high-risk' only the floor-raising codes print;
|
|
269
|
+
// on 'none' the informational codes do. Empty list → no segment at all.
|
|
270
|
+
function formatRiskFloorSegment(riskFloor = null) {
|
|
271
|
+
if (!riskFloor) {
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
const printed = riskFloor.floor === 'high-risk'
|
|
275
|
+
? riskFloor.codes.filter((code) => ROUTE_RISK_FLOOR_RAISING_CODES.has(code))
|
|
276
|
+
: riskFloor.codes;
|
|
277
|
+
return printed.length > 0 ? `risk=${riskFloor.floor}(${printed.join(',')})` : null;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// FR-001 (M01.2' limits fragment): compile the contract's numeric budget keys
|
|
281
|
+
// into an advisory map. Only finite numbers survive — a non-numeric or missing
|
|
282
|
+
// key is simply absent. Zero is a real budget ("no read passes"), never
|
|
283
|
+
// filtered. Same key set as the ceremonyBudget.limits builder below.
|
|
284
|
+
export function deriveCeremonyLimits(executionContract = null) {
|
|
285
|
+
if (executionContract === null || typeof executionContract !== 'object') {
|
|
286
|
+
return {};
|
|
287
|
+
}
|
|
288
|
+
return Object.fromEntries(
|
|
289
|
+
['maxReadPasses', 'maxContextPulls', 'maxReadPassesBeforeReassess']
|
|
290
|
+
.filter((key) => Number.isFinite(executionContract[key]))
|
|
291
|
+
.map((key) => [key, executionContract[key]]),
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Route-line segment (FR-002): fixed reads,ctx,reassess order; only present
|
|
296
|
+
// keys print. Empty/absent map → null so the segment never appears.
|
|
297
|
+
export function formatLimitsSegment(limits = null) {
|
|
298
|
+
if (limits === null || typeof limits !== 'object') {
|
|
299
|
+
return null;
|
|
300
|
+
}
|
|
301
|
+
const parts = [
|
|
302
|
+
['reads', 'maxReadPasses'],
|
|
303
|
+
['ctx', 'maxContextPulls'],
|
|
304
|
+
['reassess', 'maxReadPassesBeforeReassess'],
|
|
305
|
+
]
|
|
306
|
+
.filter(([, key]) => Number.isFinite(limits[key]))
|
|
307
|
+
.map(([label, key]) => `${label}:${limits[key]}`);
|
|
308
|
+
return parts.length > 0 ? `limits=${parts.join(',')}` : null;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// FR-004 (M01.3'): Fast Path eligibility predicate. Returns null when no riskFloor
|
|
312
|
+
// was supplied — eligibility must never be derived without the floor check, so a
|
|
313
|
+
// missing floor means "not computed", not "none". Eligible iff the lane is
|
|
314
|
+
// tiny-fix/local-fix, exactly one local target is known, the floor is 'none',
|
|
315
|
+
// a bounded verification path exists (targeted commands or the tiny-fix
|
|
316
|
+
// 'minimal-or-targeted' contract policy), and the target is not shared-impact.
|
|
317
|
+
export function deriveFastPath({
|
|
318
|
+
executionMode = null,
|
|
319
|
+
targetFile = null,
|
|
320
|
+
riskFloor = null,
|
|
321
|
+
verificationRecommendation = null,
|
|
322
|
+
contextPreview = null,
|
|
323
|
+
} = {}) {
|
|
324
|
+
if (!riskFloor) {
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
const reasons = (riskFloor.codes ?? []).filter((code) => FAST_PATH_REASON_CODES.has(code));
|
|
328
|
+
const hasLocalTarget = Boolean(targetFile) || contextPreview?.primaryTargets?.length === 1;
|
|
329
|
+
const hasBoundedVerification = (verificationRecommendation?.commands?.length ?? 0) > 0
|
|
330
|
+
|| buildExecutionContract(executionMode)?.verificationPolicy === 'minimal-or-targeted';
|
|
331
|
+
const eligible = FAST_PATH_MODES.has(executionMode)
|
|
332
|
+
&& hasLocalTarget
|
|
333
|
+
&& riskFloor.floor === 'none'
|
|
334
|
+
&& hasBoundedVerification
|
|
335
|
+
&& !isSharedImpactFile(targetFile);
|
|
336
|
+
return {
|
|
337
|
+
eligible,
|
|
338
|
+
suppressed: eligible ? [...FAST_PATH_SUPPRESSED] : [],
|
|
339
|
+
reasons,
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Route-line segment (FR-004): emitted only for eligible routes — ineligible
|
|
344
|
+
// routes keep the routeSummary.fastPath field for telemetry but stay silent.
|
|
345
|
+
function formatFastPathSegment(fastPath = null) {
|
|
346
|
+
if (!fastPath?.eligible) {
|
|
347
|
+
return null;
|
|
348
|
+
}
|
|
349
|
+
const reasons = fastPath.reasons?.length ? ` (${fastPath.reasons.join(',')})` : '';
|
|
350
|
+
return `fastPath=on | suppress: ${FAST_PATH_SUPPRESSED.join(',')}${reasons}`;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
|
|
172
354
|
|
|
173
355
|
// A bare delivery command ("push this to git", "đẩy bộ này lên git") performs no
|
|
174
356
|
// repository mutation the ledger could ever receipt. With no edit/review/debug/build
|
|
@@ -232,7 +414,12 @@ function buildResolvedRouteFields({
|
|
|
232
414
|
executionMode = null,
|
|
233
415
|
executionContract = null,
|
|
234
416
|
completionState = null,
|
|
417
|
+
riskFloor = null,
|
|
235
418
|
} = {}) {
|
|
419
|
+
// Decision table v2 (FR-001/FR-002): tier + effort resolve together from the
|
|
420
|
+
// contract lane and the additive riskFloor. The router cannot observe host
|
|
421
|
+
// binding capabilities, so the emitted pair is advisory text by definition.
|
|
422
|
+
const tierDecision = resolveModelTier({ executionMode, riskFloor });
|
|
236
423
|
const signalText = buildRouteSignalText(routingContext.promptText, routingContext.commandText);
|
|
237
424
|
const deliveryOnly = isDeliveryOnlyRequest({
|
|
238
425
|
signalText,
|
|
@@ -254,13 +441,15 @@ function buildResolvedRouteFields({
|
|
|
254
441
|
execution: {
|
|
255
442
|
mode: executionMode,
|
|
256
443
|
rigor: null,
|
|
444
|
+
riskFloor: riskFloor?.floor ?? null,
|
|
257
445
|
phase: null,
|
|
258
446
|
contractVersion: ROUTE_CONTRACT_VERSION,
|
|
259
|
-
modelTier:
|
|
447
|
+
modelTier: tierDecision.tier,
|
|
448
|
+
effort: tierDecision.effort,
|
|
260
449
|
},
|
|
261
450
|
evidence: {
|
|
262
451
|
observations: [],
|
|
263
|
-
riskSignals: [],
|
|
452
|
+
riskSignals: riskFloor?.codes ?? [],
|
|
264
453
|
activationReasons: [],
|
|
265
454
|
suppressionReasons: [],
|
|
266
455
|
completionRequirements: unique(completionState?.missingEvidence ?? []),
|
|
@@ -268,7 +457,13 @@ function buildResolvedRouteFields({
|
|
|
268
457
|
ceremonyBudget: {
|
|
269
458
|
policyVersion: ROUTE_CONTRACT_VERSION,
|
|
270
459
|
rigor: null,
|
|
271
|
-
limits:
|
|
460
|
+
limits: riskFloor
|
|
461
|
+
? Object.fromEntries(
|
|
462
|
+
['maxReadPasses', 'maxContextPulls', 'maxReadPassesBeforeReassess']
|
|
463
|
+
.filter((key) => typeof executionContract?.[key] === 'number')
|
|
464
|
+
.map((key) => [key, executionContract[key]]),
|
|
465
|
+
)
|
|
466
|
+
: {},
|
|
272
467
|
consumed: {},
|
|
273
468
|
exceptions: [],
|
|
274
469
|
},
|
|
@@ -324,12 +519,19 @@ export function validateResolvedRoute(route = null) {
|
|
|
324
519
|
if (route.execution.rigor !== null && !ROUTE_RIGOR_LEVELS.has(route.execution.rigor)) {
|
|
325
520
|
errors.push(`execution.rigor must be null or one of: ${[...ROUTE_RIGOR_LEVELS].join(', ')}.`);
|
|
326
521
|
}
|
|
522
|
+
if (route.execution.riskFloor !== null && !ROUTE_RISK_FLOORS.has(route.execution.riskFloor)) {
|
|
523
|
+
errors.push(`execution.riskFloor must be null or one of: ${[...ROUTE_RISK_FLOORS].join(', ')}.`);
|
|
524
|
+
}
|
|
327
525
|
if (route.execution.contractVersion !== ROUTE_CONTRACT_VERSION) {
|
|
328
526
|
errors.push(`execution.contractVersion must be ${ROUTE_CONTRACT_VERSION}.`);
|
|
329
527
|
}
|
|
330
528
|
if (route.execution.modelTier !== null && !ROUTE_MODEL_TIERS.has(route.execution.modelTier)) {
|
|
331
529
|
errors.push(`execution.modelTier must be null or one of: ${[...ROUTE_MODEL_TIERS].join(', ')}.`);
|
|
332
530
|
}
|
|
531
|
+
if (route.execution.effort !== null && route.execution.effort !== undefined
|
|
532
|
+
&& !ROUTE_EFFORTS.has(route.execution.effort)) {
|
|
533
|
+
errors.push(`execution.effort must be null or one of: ${[...ROUTE_EFFORTS].join(', ')}.`);
|
|
534
|
+
}
|
|
333
535
|
}
|
|
334
536
|
if (!isObject(route.evidence)) {
|
|
335
537
|
errors.push('evidence must be an object.');
|
|
@@ -339,6 +541,12 @@ export function validateResolvedRoute(route = null) {
|
|
|
339
541
|
errors.push(`evidence.${key} must be an array.`);
|
|
340
542
|
}
|
|
341
543
|
}
|
|
544
|
+
if (Array.isArray(route.evidence.riskSignals)
|
|
545
|
+
&& route.evidence.riskSignals.some(
|
|
546
|
+
(code) => typeof code !== 'string' || !ROUTE_RISK_REASON_CODES.includes(code),
|
|
547
|
+
)) {
|
|
548
|
+
errors.push(`evidence.riskSignals entries must be one of: ${ROUTE_RISK_REASON_CODES.join(', ')}.`);
|
|
549
|
+
}
|
|
342
550
|
}
|
|
343
551
|
if (!isObject(route.ceremonyBudget)) {
|
|
344
552
|
errors.push('ceremonyBudget must be an object.');
|
|
@@ -667,6 +875,48 @@ export function buildRouteSummary({
|
|
|
667
875
|
nextActionType: nextAction?.type ?? null,
|
|
668
876
|
completionState,
|
|
669
877
|
});
|
|
878
|
+
// FR-003 (M01.2'): riskFloor is a top-level additive field emitted whenever ANY
|
|
879
|
+
// of rigor/fastPath/escalation stages is on — fastPath/escalation consumers read
|
|
880
|
+
// it even when routeSchema is off. All three off → absent, byte-identical route.
|
|
881
|
+
const riskStageOn = ['rigor', 'fastPath', 'escalation']
|
|
882
|
+
.some((key) => resolveRouteStage(runtimeConfig, key) !== 'off');
|
|
883
|
+
const riskFloor = riskStageOn
|
|
884
|
+
? deriveRiskFloor({
|
|
885
|
+
promptText: routingContext.promptText,
|
|
886
|
+
commandText: routingContext.commandText,
|
|
887
|
+
targetFile: routingContext.targetFile ?? null,
|
|
888
|
+
executionMode,
|
|
889
|
+
activeSkillIds: activeSkills.map((entry) => entry.id),
|
|
890
|
+
contextPreview: contextRecommendation?.preview ?? null,
|
|
891
|
+
})
|
|
892
|
+
: null;
|
|
893
|
+
const riskSegment = formatRiskFloorSegment(riskFloor);
|
|
894
|
+
// FR-003 (M01.2' limits fragment): the rigor advisory — emitted whenever
|
|
895
|
+
// rigor.stage is on, independent of fastPath/escalation. Stage off → no
|
|
896
|
+
// segment, byte-identical route.
|
|
897
|
+
const limitsSegment = resolveRouteStage(runtimeConfig, 'rigor') !== 'off'
|
|
898
|
+
? formatLimitsSegment(deriveCeremonyLimits(executionContract))
|
|
899
|
+
: null;
|
|
900
|
+
// FR-004 (M01.3'): fastPath is emitted whenever its own stage is on — the field
|
|
901
|
+
// is always set then (eligible or not) so telemetry/harness can read it; the
|
|
902
|
+
// route-line segment prints only for eligible routes.
|
|
903
|
+
const fastPathStage = resolveRouteStage(runtimeConfig, 'fastPath');
|
|
904
|
+
const fastPath = fastPathStage !== 'off'
|
|
905
|
+
? {
|
|
906
|
+
eligible: false,
|
|
907
|
+
suppressed: [],
|
|
908
|
+
reasons: [],
|
|
909
|
+
...deriveFastPath({
|
|
910
|
+
executionMode,
|
|
911
|
+
targetFile: routingContext.targetFile ?? null,
|
|
912
|
+
riskFloor,
|
|
913
|
+
verificationRecommendation,
|
|
914
|
+
contextPreview: contextRecommendation?.preview ?? null,
|
|
915
|
+
}),
|
|
916
|
+
stage: fastPathStage,
|
|
917
|
+
}
|
|
918
|
+
: null;
|
|
919
|
+
const fastPathSegment = formatFastPathSegment(fastPath);
|
|
670
920
|
const resolvedRouteFields = routeSchemaStage !== 'off'
|
|
671
921
|
? buildResolvedRouteFields({
|
|
672
922
|
routingContext,
|
|
@@ -674,6 +924,7 @@ export function buildRouteSummary({
|
|
|
674
924
|
executionMode,
|
|
675
925
|
executionContract,
|
|
676
926
|
completionState,
|
|
927
|
+
riskFloor,
|
|
677
928
|
})
|
|
678
929
|
: null;
|
|
679
930
|
const helperHint = compactHelperHint(
|
|
@@ -716,6 +967,9 @@ export function buildRouteSummary({
|
|
|
716
967
|
formatCompactSegment('tests', relatedTests),
|
|
717
968
|
formatCompactSegment('styles', styleFiles),
|
|
718
969
|
editGuardHint ? `editGuard=${editGuardHint}` : null,
|
|
970
|
+
riskSegment,
|
|
971
|
+
limitsSegment,
|
|
972
|
+
fastPathSegment,
|
|
719
973
|
delegationRecommendation?.hint ? `delegate=${delegationRecommendation.hint}` : null,
|
|
720
974
|
policyMode ? `policy=${policyMode}` : null,
|
|
721
975
|
workflowPolicyName ? `workflow=${workflowPolicyName}` : null,
|
|
@@ -737,6 +991,10 @@ export function buildRouteSummary({
|
|
|
737
991
|
completionState,
|
|
738
992
|
// M01.1 additive C01 groups — present only when routing.routeSchema.stage != "off".
|
|
739
993
|
...(resolvedRouteFields ?? {}),
|
|
994
|
+
// FR-003 additive top-level field — present only when a risk stage is on.
|
|
995
|
+
...(riskFloor ? { riskFloor } : {}),
|
|
996
|
+
// FR-004 additive top-level field — present only when fastPath stage is on.
|
|
997
|
+
...(fastPath ? { fastPath } : {}),
|
|
740
998
|
continuationState,
|
|
741
999
|
autonomyLevel,
|
|
742
1000
|
continuousExecution,
|
|
@@ -864,7 +1122,7 @@ function deriveExecutionScores({
|
|
|
864
1122
|
// asking for an explanation, not a repository change. Routing it to an investigation or
|
|
865
1123
|
// edit lane fabricates write/verification debt the completion gate then enforces against an
|
|
866
1124
|
// answer turn. Kept byte-equivalent to the shipped copies in
|
|
867
|
-
//
|
|
1125
|
+
// template_project/.claude/ukit/index/route-task.mjs and template_project/.claude/hooks/skill-router.sh;
|
|
868
1126
|
// this is the canonical copy those are mirror-tested against. It deliberately ignores
|
|
869
1127
|
// targetFile: an edit order phrased as a question is caught by implementWords below, while a
|
|
870
1128
|
// pure targeted question ("how does X work?") is still just a question.
|
|
@@ -173,11 +173,11 @@ export function renderAll(layout, sourceTexts, varsByResolve = {}) {
|
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
const SOURCE_FILES = {
|
|
176
|
-
core: '
|
|
177
|
-
'overlay:claude': '
|
|
178
|
-
'overlay:agents': '
|
|
179
|
-
'overlay:omp-rules': '
|
|
180
|
-
'overlay:repo': '
|
|
176
|
+
core: 'template_project/instructions/core.md',
|
|
177
|
+
'overlay:claude': 'template_project/instructions/overlays/claude.md',
|
|
178
|
+
'overlay:agents': 'template_project/instructions/overlays/agents.md',
|
|
179
|
+
'overlay:omp-rules': 'template_project/instructions/overlays/omp-rules.md',
|
|
180
|
+
'overlay:repo': 'template_project/instructions/overlays/repo.md',
|
|
181
181
|
};
|
|
182
182
|
|
|
183
183
|
/**
|
|
@@ -187,10 +187,10 @@ const SOURCE_FILES = {
|
|
|
187
187
|
export async function renderInstructionsFromDisk({ repoRoot, write = true } = {}) {
|
|
188
188
|
const abs = (p) => path.join(repoRoot, p);
|
|
189
189
|
const layout = YAML.parse(
|
|
190
|
-
fs.readFileSync(abs('
|
|
190
|
+
fs.readFileSync(abs('template_project/instructions/layout.yaml'), 'utf8'),
|
|
191
191
|
);
|
|
192
192
|
const repoVars =
|
|
193
|
-
YAML.parse(fs.readFileSync(abs('
|
|
193
|
+
YAML.parse(fs.readFileSync(abs('template_project/instructions/repo-vars.yaml'), 'utf8')) || {};
|
|
194
194
|
const pkg = JSON.parse(fs.readFileSync(abs('package.json'), 'utf8'));
|
|
195
195
|
|
|
196
196
|
const sourceTexts = {};
|
package/src/skill/auditSkill.js
CHANGED
|
@@ -23,7 +23,7 @@ export async function initSkillAudit({ rootDir = process.cwd(), skillName } = {}
|
|
|
23
23
|
const auditDir = getAuditDir(rootDir, skillName);
|
|
24
24
|
await fs.mkdir(auditDir, { recursive: true });
|
|
25
25
|
|
|
26
|
-
const templateSourceDir = path.join(rootDir, '
|
|
26
|
+
const templateSourceDir = path.join(rootDir, 'template_project/.claude/skills/skill-quality');
|
|
27
27
|
const copied = [];
|
|
28
28
|
const skipped = [];
|
|
29
29
|
|
|
@@ -57,6 +57,8 @@ If any input is missing, return `CHANGES-REQUESTED` with reason "incomplete hand
|
|
|
57
57
|
VERDICT: APPROVED | APPROVED-WITH-MINOR | CHANGES-REQUESTED | CRITICAL
|
|
58
58
|
REVIEWER_MODEL: [model name actually used]
|
|
59
59
|
EXECUTOR_MODEL: [from executor report]
|
|
60
|
+
PANEL_MEMBER: [panel tier — `smart`/`code`/`lite`, or `solo` when the panel degenerates; `-` outside panel runs]
|
|
61
|
+
AGREEMENT_MAP: [lead member only — finding → panel members reporting it, from review-panel-aggregate.mjs output; `-` otherwise]
|
|
60
62
|
VERIFICATION_RERUN:
|
|
61
63
|
command: [exact command]
|
|
62
64
|
result: [N pass / M fail]
|
|
@@ -121,6 +123,29 @@ Same model is the most common silent failure. Do not skip this check.
|
|
|
121
123
|
- Keep the verdict block <= 30 lines. Findings are bullet points, not essays.
|
|
122
124
|
- The same-model refusal above is non-negotiable: bypassing it defeats the entire Quality Gate.
|
|
123
125
|
|
|
126
|
+
## Panel review (diversity review)
|
|
127
|
+
|
|
128
|
+
When the orchestrator spawns you as one member of the `modelRoles['review-panel']`
|
|
129
|
+
panel (`.ukit/storage/config.json` → `modelRoles`, default `['smart','code','lite']`),
|
|
130
|
+
everything above applies unchanged — same Review order, same severity ladder, same
|
|
131
|
+
verdict block — with these additions:
|
|
132
|
+
|
|
133
|
+
- Set `PANEL_MEMBER: <tier>` in the verdict to your panel tier (e.g. `smart`,
|
|
134
|
+
`code`, `lite`). Every member runs the same rubric independently; do not read or
|
|
135
|
+
wait for other members' verdicts.
|
|
136
|
+
- Leave `AGREEMENT_MAP` as `-` unless you are the **lead member** (the first entry in
|
|
137
|
+
`modelRoles['review-panel']` = the judgment tier). After the orchestrator runs
|
|
138
|
+
`node .claude/ukit/index/review-panel-aggregate.mjs <TASK-xxx.md...>` and hands you
|
|
139
|
+
the output, the lead fills `AGREEMENT_MAP` with the emitted finding → members map
|
|
140
|
+
and applies the lead-judgment buckets to every finding: **Act on** / **Consider** /
|
|
141
|
+
**Noted** / **Dismissed**.
|
|
142
|
+
- `consensus≥2 identical findings = high signal`: a finding reported by two or more
|
|
143
|
+
panel members is high-signal and must not be bucketed below **Consider** without a
|
|
144
|
+
stated reason.
|
|
145
|
+
- Degenerate panel: if `modelRoles['review-panel']` is empty or has one entry, the
|
|
146
|
+
panel collapses to a single reviewer — run the normal solo review, set
|
|
147
|
+
`PANEL_MEMBER: solo`, and note the fallback in `NOTES`.
|
|
148
|
+
|
|
124
149
|
## Spec/Plan Review (REVIEW_TARGET_TYPE=spec|plan)
|
|
125
150
|
|
|
126
151
|
### Inputs you expect
|
|
@@ -76,7 +76,7 @@ verification — link both files' `## Discussion` threads.
|
|
|
76
76
|
|
|
77
77
|
## Phase 0.5 — Write SPEC.md
|
|
78
78
|
|
|
79
|
-
Write `docs/AI_HANDOFF/SPEC.md` from the template at `
|
|
79
|
+
Write `docs/AI_HANDOFF/SPEC.md` from the template at `template_project/docs/AI_HANDOFF/SPEC.md`
|
|
80
80
|
(15 sections). The spec is the contract executors implement against — concrete enough that
|
|
81
81
|
nothing is guessed: exact paths, module and API names, schemas, validation rules,
|
|
82
82
|
permissions, empty/error states, migration behavior, test expectations. Every section is
|
|
@@ -135,7 +135,7 @@ Use `_TEMPLATE.md` structure (from pre-read context or file).
|
|
|
135
135
|
| Dependencies | `TASK-xxx` or `none` — wave order is inferred from this |
|
|
136
136
|
| Test Cases | Type \| Test Name \| Expected — ≥1 happy + ≥2 edge cases of different kinds |
|
|
137
137
|
| Test Files | Exact test file paths to create/modify |
|
|
138
|
-
| Verification Commands | Runnable shell commands — MUST include the project's lint/typecheck command if one exists (see §5 rule above). Apply the "Test selection" resolution order from docs/AI_HANDOFF/RULES.md: `src/`/`scripts/` targets → the `tests` array in `.cache/index/tests-map.json`; `
|
|
138
|
+
| Verification Commands | Runnable shell commands — MUST include the project's lint/typecheck command if one exists (see §5 rule above). Apply the "Test selection" resolution order from docs/AI_HANDOFF/RULES.md: `src/`/`scripts/` targets → the `tests` array in `.cache/index/tests-map.json`; `template_project/.claude/**`/`.claude/**` targets → path convention (hooks → `tests/hooks/` + `tests/handoff/cycle*/`; manifest/settings → `tests/manifest/`; runtime `.mjs` mirrors → `tests/core/*Parity*` + `tests/index/`); if both resolve to fewer than one test file the task MUST fall back to `yarn test:release-core` — never the full suite by default, never an empty selection |
|
|
139
139
|
| Acceptance Criteria | Verifiable checklist |
|
|
140
140
|
|
|
141
141
|
Missing any field → `needs_breakdown`. Never mark incomplete tasks `ready`.
|
|
@@ -196,6 +196,21 @@ Status: planning_done — ready for executor
|
|
|
196
196
|
```
|
|
197
197
|
Wave structure is NOT stored here — inferred from task `Dependencies` fields at runtime.
|
|
198
198
|
|
|
199
|
+
**RUN.md** — write the run's `ExitPredicate:` line before iteration 1 (the orchestrator
|
|
200
|
+
keeps it verbatim on every cursor rewrite):
|
|
201
|
+
|
|
202
|
+
```
|
|
203
|
+
ExitPredicate: all(index:all-done, git:clean)
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Grammar: `all(<term>[,<term>...])` or a single term; terms are `index:all-done`,
|
|
207
|
+
`git:clean`, `file-exists:<relpath>` (repo-relative, no `..` segments). Default to
|
|
208
|
+
`all(index:all-done, git:clean)`; add `file-exists:` terms only for artifacts the plan
|
|
209
|
+
itself must produce. The stop gate evaluates this mechanically when the cursor claims
|
|
210
|
+
`Phase: done` — a `done` claim with failing terms is bounced back with the per-term
|
|
211
|
+
state. **Never relax the predicate mid-run**: if the run cannot satisfy it, the plan is
|
|
212
|
+
wrong — fix the plan, not the gate.
|
|
213
|
+
|
|
199
214
|
## Self-Audit — run before reporting, every time
|
|
200
215
|
|
|
201
216
|
The downstream pipeline is unattended: an incomplete or wrong plan is not caught by a human
|
|
@@ -70,7 +70,7 @@ The planner agent does the following (use Step 1 summary — do NOT re-read file
|
|
|
70
70
|
```
|
|
71
71
|
|
|
72
72
|
3. Write `docs/AI_HANDOFF/SPEC.md` — the detailed implementation spec (BẮT BUỘC before tasks).
|
|
73
|
-
Follow `docs/AI_HANDOFF/SPEC.md`'s template sections (or `
|
|
73
|
+
Follow `docs/AI_HANDOFF/SPEC.md`'s template sections (or `template_project/docs/AI_HANDOFF/SPEC.md`
|
|
74
74
|
on a fresh tree): problem/context, goals, non-goals, user journeys, functional requirements
|
|
75
75
|
with Given/When/Then + error cases, fullstack scope (backend, schema/migrations, API
|
|
76
76
|
contract, UI+state, integration, security, performance, observability, deploy/rollback),
|
|
@@ -59,7 +59,7 @@ resumable. If compaction does happen, the run resumes from the cursor automatica
|
|
|
59
59
|
|
|
60
60
|
### Run cursor — write after every step
|
|
61
61
|
|
|
62
|
-
Maintain `docs/AI_HANDOFF/RUN.md`. Rewrite it (whole file,
|
|
62
|
+
Maintain `docs/AI_HANDOFF/RUN.md`. Rewrite it (whole file, 7 lines) immediately after every
|
|
63
63
|
numbered step completes:
|
|
64
64
|
|
|
65
65
|
```
|
|
@@ -69,9 +69,15 @@ Base: <BASE branch>
|
|
|
69
69
|
Phase: <P0|P1|P2|P2.5|P3|I1|I2|I3|I4|R1|R2|R3|R4|R4.5|R5|F|done|blocked>
|
|
70
70
|
Cursor: wave <N> batch <M> — <what just finished>
|
|
71
71
|
Next: <the exact next step to run>
|
|
72
|
+
ExitPredicate: all(<term>[,<term>...]) # written once at P2; never relaxed
|
|
72
73
|
QuietScans: <n>/<required> # only while sweeping for stragglers near the end
|
|
73
74
|
```
|
|
74
75
|
|
|
76
|
+
`ExitPredicate` grammar: `all(<term>[,<term>...])` or a single term; terms are
|
|
77
|
+
`index:all-done`, `git:clean`, `file-exists:<relpath>`. The stop gate evaluates it
|
|
78
|
+
mechanically when the cursor claims `Phase: done` — a `done` claim with failing terms
|
|
79
|
+
is bounced back with the per-term state. Keep the line verbatim on every rewrite.
|
|
80
|
+
|
|
75
81
|
This file is the resume contract. It costs one small write per step and is what turns an
|
|
76
82
|
interrupted run into a continuable one.
|
|
77
83
|
|
|
@@ -172,9 +178,12 @@ The run must keep itself alive without the human watching.
|
|
|
172
178
|
|
|
173
179
|
- **Stop gate (Claude Code, automatic):** while `RUN.md` `Phase:` is not `done`/`blocked`,
|
|
174
180
|
`completion-gate.sh` refuses the stop with the cursor's `Next:` step. Recaps and
|
|
175
|
-
premature stops cannot park the run.
|
|
181
|
+
premature stops cannot park the run. When RUN.md carries `ExitPredicate:`, a
|
|
182
|
+
`Phase: done` whose predicate fails is refused too — `done` means the predicate
|
|
183
|
+
evaluates true. A stalled-cursor breaker
|
|
176
184
|
(`handoff.fullstack.stopGateMaxStalledBlocks`, default 12) releases the session if the
|
|
177
|
-
cursor has genuinely stopped advancing — the escape hatch, not the norm
|
|
185
|
+
cursor has genuinely stopped advancing — the escape hatch, not the norm — and its
|
|
186
|
+
release advisory reports the predicate state, so a plateau is visible, not silent.
|
|
178
187
|
- **Scheduled wakeup (when the harness offers one):** arm it at run start — Claude Code:
|
|
179
188
|
`CronCreate` a ~`handoff.fullstack.idleWatchdogMin`-minute (default 5) session job with
|
|
180
189
|
prompt `Resume HANDOFF FULLSTACK from docs/AI_HANDOFF/RUN.md — continue the Next: step`;
|
|
@@ -222,7 +231,7 @@ The planner agent does the following (use P1 summary — do NOT re-read files):
|
|
|
222
231
|
```
|
|
223
232
|
|
|
224
233
|
3. **Write `docs/AI_HANDOFF/SPEC.md`** — the detailed implementation spec, from
|
|
225
|
-
`
|
|
234
|
+
`template_project/docs/AI_HANDOFF/SPEC.md`'s section list (or RULES.md §Spec). It must be
|
|
226
235
|
concrete enough that an executor implements without guessing: exact paths, module and
|
|
227
236
|
API names, schemas, validation rules, permissions, empty/error states, migration
|
|
228
237
|
behavior, and test expectations — every applicable section filled, open questions
|
|
@@ -269,7 +278,13 @@ The planner agent does the following (use P1 summary — do NOT re-read files):
|
|
|
269
278
|
```
|
|
270
279
|
Then **verify the write** (read back the `Status:` line).
|
|
271
280
|
|
|
272
|
-
8. **
|
|
281
|
+
8. **Write `ExitPredicate:` into `docs/AI_HANDOFF/RUN.md`** — the mechanical definition of
|
|
282
|
+
done for this run: `all(<term>[,<term>...])` over `index:all-done`, `git:clean`,
|
|
283
|
+
`file-exists:<relpath>` (default `all(index:all-done, git:clean)`). Written once,
|
|
284
|
+
before iteration 1, and **never relaxed** — if the run cannot satisfy it, the plan is
|
|
285
|
+
wrong, not the gate. Then **verify the write** (read back the `ExitPredicate:` line).
|
|
286
|
+
|
|
287
|
+
9. **Report:** task IDs, dependency graph, recovery/superseded tasks, any
|
|
273
288
|
`needs_breakdown` tasks + reason.
|
|
274
289
|
|
|
275
290
|
### P2.5 — Independent plan review (strong model, separate agent)
|
|
@@ -455,7 +470,12 @@ Worktrees are **always deleted immediately** — no exceptions.
|
|
|
455
470
|
A wave boundary is the only safe place to shed context, because everything of value is
|
|
456
471
|
already on disk (task files hold the full logs, git holds the code). Do all four, in order:
|
|
457
472
|
|
|
458
|
-
1. **Checkpoint the code
|
|
473
|
+
1. **Checkpoint the code — commit-if-advanced.** One commit per wave, so every wave is
|
|
474
|
+
independently revertible — but only when the wave's diff advances the run's
|
|
475
|
+
`ExitPredicate` (a task moved toward `done`, a required file appeared, the worktree
|
|
476
|
+
got cleaner). A wave whose diff does not advance the predicate is **discarded**: its
|
|
477
|
+
copied-back changes are reverted and nothing is committed. A plateau is not a stop —
|
|
478
|
+
the run continues to the next wave or fix round; the predicate is never relaxed.
|
|
459
479
|
```bash
|
|
460
480
|
git add -A && git commit -m "handoff: wave <N> — TASK-00x, TASK-00y"
|
|
461
481
|
```
|
|
@@ -54,9 +54,11 @@ If that diff is empty → handoff-implement was not completed. Report which task
|
|
|
54
54
|
|
|
55
55
|
**Batch the review set — mandatory.** Read `handoff.maxParallelAgents` from `.ukit/storage/config.json`. If more `pending_review` tasks exist than that, split into consecutive batches of at most that many; finish one batch's verdicts (2a–2d, appended to each task file) before starting the next.
|
|
56
56
|
|
|
57
|
-
**
|
|
57
|
+
**Spawn the review panel — MANDATORY, do this before anything else:** read `modelRoles['review-panel']` from `.ukit/storage/config.json` → `modelRoles` (default `['smart','code','lite']`; omp tier aliases `@smol`/`@default`/`@slow`). For each `pending_review` task in the batch, call the Agent tool **once per panel entry** (in parallel, bounded by `handoff.maxParallelAgents`), each with `subagent_type: "code-reviewer"` (omp: the `task` tool with `agent: "code-reviewer"`, likewise invoked once per panel entry per task) — each member bound to its panel tier and setting `PANEL_MEMBER: <tier>` in its verdict. Reviewer agents only read the diff and append a verdict to their own task file — no worktree, no shared write target — so running them in parallel carries none of Phase 3's file-conflict risk. Do NOT review the diff yourself in the current session — this step is contracted to the panel tiers and MUST differ from the executor's model, which only the spawned agent's frontmatter model guarantees. Pass each agent: the task file path, the executor's report, and the diff.
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
Degenerate panel: if `modelRoles['review-panel']` is empty or has one entry, spawn a single reviewer and require `PANEL_MEMBER: solo` in its verdict.
|
|
60
|
+
|
|
61
|
+
Each spawned reviewer agent performs 2a–2d below per task:
|
|
60
62
|
|
|
61
63
|
### 2a — Model isolation check (always first)
|
|
62
64
|
|
|
@@ -98,6 +100,7 @@ matches the task file's wording.
|
|
|
98
100
|
VERDICT: approved | approved_minor | changes_requested | critical_block
|
|
99
101
|
REVIEWER_MODEL: <your exact model ID>
|
|
100
102
|
EXECUTOR_MODEL: <from Executor Report>
|
|
103
|
+
PANEL_MEMBER: <panel tier | solo | ->
|
|
101
104
|
VERIFICATION_RERUN: PASS | FAIL
|
|
102
105
|
FINDINGS:
|
|
103
106
|
critical: <file:line — what fails> | none
|
|
@@ -116,7 +119,29 @@ BLOCKING: <one line per critical/important finding, or "none">
|
|
|
116
119
|
```
|
|
117
120
|
Do not paste the diff, the findings prose, or verification logs back into the orchestrator.
|
|
118
121
|
|
|
119
|
-
### 2e —
|
|
122
|
+
### 2e — Aggregate the panel + lead bucketing
|
|
123
|
+
|
|
124
|
+
Once every panel member for a task has appended its `## Reviewer Verdict`, run:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
node .claude/ukit/index/review-panel-aggregate.mjs docs/AI_HANDOFF/tasks/TASK-xxx.md
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The script emits an Agreement Map (finding → set of panel members reporting it) and a
|
|
131
|
+
consensus verdict (`approved` when ≥2 members approve and no critical;
|
|
132
|
+
`changes_requested` when ≥1 critical or ≥2 request changes; else `approved_minor`).
|
|
133
|
+
`consensus≥2 identical findings = high signal` — a finding reported by two or more
|
|
134
|
+
members is high-signal. The consensus verdict, not any single member's vote, drives
|
|
135
|
+
`NEXT_STATUS_FOR_INDEX`.
|
|
136
|
+
|
|
137
|
+
Then the **lead member** (first entry in `modelRoles['review-panel']` = the judgment
|
|
138
|
+
tier) applies the lead-judgment buckets to every finding — **Act on** / **Consider** /
|
|
139
|
+
**Noted** / **Dismissed** — and appends a `## Panel Consensus` block to the task file
|
|
140
|
+
carrying the Agreement Map and the bucketed findings. `Act on` findings feed Step 3's
|
|
141
|
+
auto-fix loop; `Consider`/`Noted`/`Dismissed` are advisory. A high-signal finding must
|
|
142
|
+
not be bucketed below `Consider` without a stated reason.
|
|
143
|
+
|
|
144
|
+
### 2f — Orchestrator updates INDEX.md
|
|
120
145
|
|
|
121
146
|
Set `status = NEXT_STATUS_FOR_INDEX`. Orchestrator writes INDEX, not the reviewer.
|
|
122
147
|
|
|
@@ -144,7 +169,7 @@ For round in 1..2:
|
|
|
144
169
|
```bash
|
|
145
170
|
git add -A && git commit -m "handoff: fix round <N> — TASK-00x"
|
|
146
171
|
```
|
|
147
|
-
4. Re-review **only the tasks touched this round**, in parallel, per 2a–
|
|
172
|
+
4. Re-review **only the tasks touched this round**, in parallel, per 2a–2f — panel spawn, aggregation, and lead bucketing included. The reviewers must
|
|
148
173
|
still differ from the executor model and still re-runs verification itself.
|
|
149
174
|
5. Update `INDEX.md` and `RUN.md`. Exit when everything is approved.
|
|
150
175
|
|
|
@@ -190,5 +215,5 @@ Then, as the last line:
|
|
|
190
215
|
This is the only place this command may ask for a compaction. All state lives in git,
|
|
191
216
|
`INDEX.md` and `RUN.md`, so a compacted or fresh session resumes with nothing lost.
|
|
192
217
|
|
|
193
|
-
> Orchestrator (this session) handles Step 1, 2e, and 3 directly — those are not delegated.
|
|
194
|
-
> **For the human operator, on a tool with no agent support (Codex) — not an instruction to the model:** manually switch to the strong model, run 2a–2d per task (one session at a time).
|
|
218
|
+
> Orchestrator (this session) handles Step 1, 2e, 2f, and 3 directly — those are not delegated.
|
|
219
|
+
> **For the human operator, on a tool with no agent support (Codex) — not an instruction to the model:** manually switch to the strong model, run 2a–2d per task (one session at a time, panel members sequentially), then run `review-panel-aggregate.mjs` and apply the lead buckets yourself.
|