@event4u/agent-config 14.23.0 → 16.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.augment-plugin/marketplace.json +3 -3
- package/.augment-plugin/plugin.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +144 -152
- package/README.md +1 -1
- package/dist/agent-src/commands/agent-handoff.md +8 -7
- package/dist/agent-src/commands/agents/init.md +1 -1
- package/dist/agent-src/commands/agents/user/accept.md +4 -4
- package/dist/agent-src/commands/agents/user/delete.md +2 -2
- package/dist/agent-src/commands/agents/user/init.md +3 -3
- package/dist/agent-src/commands/agents/user/review.md +3 -3
- package/dist/agent-src/commands/agents/user/show.md +3 -3
- package/dist/agent-src/commands/agents/user/update.md +2 -2
- package/dist/agent-src/commands/agents/user.md +6 -6
- package/dist/agent-src/commands/analytics/prune.md +1 -1
- package/dist/agent-src/commands/analytics/show.md +2 -2
- package/dist/agent-src/commands/analyze/decision.md +2 -2
- package/dist/agent-src/commands/analyze/inbox.md +5 -5
- package/dist/agent-src/commands/analyze/incident.md +3 -3
- package/dist/agent-src/commands/analyze/near-miss.md +3 -3
- package/dist/agent-src/commands/analyze/postmortem.md +4 -4
- package/dist/agent-src/commands/analyze/premortem.md +2 -2
- package/dist/agent-src/commands/analyze.md +2 -2
- package/dist/agent-src/commands/bug/fix.md +1 -1
- package/dist/agent-src/commands/bug/investigate.md +2 -2
- package/dist/agent-src/commands/cost/profile.md +3 -3
- package/dist/agent-src/commands/design.md +1 -1
- package/dist/agent-src/commands/feature/explore.md +1 -1
- package/dist/agent-src/commands/feature/plan.md +2 -2
- package/dist/agent-src/commands/feature/roadmap.md +2 -2
- package/dist/agent-src/commands/ghostwriter/fetch.md +4 -4
- package/dist/agent-src/commands/ghostwriter/list.md +1 -1
- package/dist/agent-src/commands/ghostwriter/show.md +1 -1
- package/dist/agent-src/commands/ghostwriter/write.md +9 -9
- package/dist/agent-src/commands/humanize.md +6 -6
- package/dist/agent-src/commands/jira-ticket.md +1 -1
- package/dist/agent-src/commands/judge/solo.md +1 -1
- package/dist/agent-src/commands/judge.md +1 -1
- package/dist/agent-src/commands/knowledge/cross-repo.md +1 -1
- package/dist/agent-src/commands/knowledge/forget.md +1 -1
- package/dist/agent-src/commands/knowledge/ingest.md +2 -2
- package/dist/agent-src/commands/knowledge/list.md +1 -1
- package/dist/agent-src/commands/memory/add.md +3 -3
- package/dist/agent-src/commands/memory/load.md +4 -4
- package/dist/agent-src/commands/memory/mine-session.md +1 -1
- package/dist/agent-src/commands/memory/promote.md +4 -4
- package/dist/agent-src/commands/memory/propose.md +2 -2
- package/dist/agent-src/commands/mode.md +5 -5
- package/dist/agent-src/commands/post-as/ghostwriter.md +3 -3
- package/dist/agent-src/commands/post-as/me.md +7 -7
- package/dist/agent-src/commands/pr/create.md +1 -1
- package/dist/agent-src/commands/pr/merge.md +1 -1
- package/dist/agent-src/commands/profile/activate.md +1 -1
- package/dist/agent-src/commands/profile/show.md +1 -1
- package/dist/agent-src/commands/research/deep.md +2 -2
- package/dist/agent-src/commands/research/report.md +2 -2
- package/dist/agent-src/commands/review/changes.md +1 -1
- package/dist/agent-src/commands/review/routing.md +1 -1
- package/dist/agent-src/commands/roadmap/create.md +4 -3
- package/dist/agent-src/commands/roadmap/materialize.md +2 -2
- package/dist/agent-src/commands/roadmap/next.md +1 -1
- package/dist/agent-src/commands/roadmap/process-full.md +2 -2
- package/dist/agent-src/commands/security-audit-config.md +3 -3
- package/dist/agent-src/commands/skill/preview.md +1 -1
- package/dist/agent-src/commands/skills/discover.md +1 -1
- package/dist/agent-src/commands/sync/agent-settings.md +2 -2
- package/dist/agent-src/commands/sync/gitignore/fix.md +1 -1
- package/dist/agent-src/commands/tests/create.md +1 -1
- package/dist/agent-src/commands/tests/e2e-heal.md +1 -1
- package/dist/agent-src/commands/tests/e2e-plan.md +1 -1
- package/dist/agent-src/contexts/authority/kernel-rule-edits.md +6 -6
- package/dist/agent-src/contexts/communication/rules-auto/slash-command-routing-policy-mechanics.md +1 -2
- package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +2 -2
- package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +88 -1
- package/dist/agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +51 -1
- package/dist/agent-src/contexts/contracts/frugality-charter.md +1 -1
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +1 -1
- package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +1 -1
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +1 -1
- package/dist/agent-src/contexts/execution/cheap-question-mechanics.md +1 -1
- package/dist/agent-src/contexts/execution/contract-decision-sheet.md +3 -3
- package/dist/agent-src/contexts/execution/mandated-lines.md +1 -1
- package/dist/agent-src/contexts/execution/non-interactive-contract.md +1 -1
- package/dist/agent-src/contexts/execution/orchestration-telemetry.md +1 -1
- package/dist/agent-src/contexts/execution/plan-confidence-gate.md +5 -5
- package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +1 -1
- package/dist/agent-src/contexts/execution/subagent-modes-detail.md +1 -1
- package/dist/agent-src/contexts/execution/subagent-routing.md +2 -2
- package/dist/agent-src/contexts/execution/subagent-spawn-contract.md +1 -1
- package/dist/agent-src/contexts/execution/user-memory-channels.md +3 -3
- package/dist/agent-src/contexts/execution/verification-mechanics.md +1 -1
- package/dist/agent-src/contexts/judges/persona-voice-rubric.md +2 -2
- package/dist/agent-src/guidelines/abstraction-thresholds.md +88 -0
- package/dist/agent-src/guidelines/agent-infra/5w2h-analysis.md +260 -0
- package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +99 -0
- package/dist/agent-src/guidelines/agent-infra/agent-interaction-and-decision-quality.md +325 -0
- package/dist/agent-src/guidelines/agent-infra/api-cost-levers.md +177 -0
- package/dist/agent-src/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +222 -0
- package/dist/agent-src/guidelines/agent-infra/ask-when-uncertain-demos.md +134 -0
- package/dist/agent-src/guidelines/agent-infra/asking-and-brevity-examples.md +198 -0
- package/dist/agent-src/guidelines/agent-infra/break-glass-usage.md +113 -0
- package/dist/agent-src/guidelines/agent-infra/carve-out-predicates.md +17 -0
- package/dist/agent-src/guidelines/agent-infra/comparison-matrix.md +179 -0
- package/dist/agent-src/guidelines/agent-infra/context-hygiene-mechanics.md +165 -0
- package/dist/agent-src/guidelines/agent-infra/corpus-grounding-authoring.md +91 -0
- package/dist/agent-src/guidelines/agent-infra/critical-thinking.md +156 -0
- package/dist/agent-src/guidelines/agent-infra/cross-source-consistency-mechanics.md +109 -0
- package/dist/agent-src/guidelines/agent-infra/developer-judgment.md +82 -0
- package/dist/agent-src/guidelines/agent-infra/direct-answers-demos.md +142 -0
- package/dist/agent-src/guidelines/agent-infra/domain-adoption-gates.md +112 -0
- package/dist/agent-src/guidelines/agent-infra/domain-eval-anti-pattern.md +53 -0
- package/dist/agent-src/guidelines/agent-infra/domain-pack-architecture.md +56 -0
- package/dist/agent-src/guidelines/agent-infra/downstream-changes-mechanics.md +91 -0
- package/dist/agent-src/guidelines/agent-infra/emphasis-budget.md +45 -0
- package/dist/agent-src/guidelines/agent-infra/engineering-memory-data-format.md +210 -0
- package/dist/agent-src/guidelines/agent-infra/evaluator-independence-mechanics.md +92 -0
- package/dist/agent-src/guidelines/agent-infra/existence-question-verdicts.md +80 -0
- package/dist/agent-src/guidelines/agent-infra/failure-signatures.md +70 -0
- package/dist/agent-src/guidelines/agent-infra/false-green.md +233 -0
- package/dist/agent-src/guidelines/agent-infra/first-principles.md +192 -0
- package/dist/agent-src/guidelines/agent-infra/framework-neutrality-patterns.md +66 -0
- package/dist/agent-src/guidelines/agent-infra/frontier-reasoning-operating-profile.md +169 -0
- package/dist/agent-src/guidelines/agent-infra/gate-authoring.md +177 -0
- package/dist/agent-src/guidelines/agent-infra/guarded-baseline.md +39 -0
- package/dist/agent-src/guidelines/agent-infra/installed-tools-manifest.md +142 -0
- package/dist/agent-src/guidelines/agent-infra/inversion-thinking.md +388 -0
- package/dist/agent-src/guidelines/agent-infra/ios-simulator-guide.md +378 -0
- package/dist/agent-src/guidelines/agent-infra/language-and-tone-examples.md +141 -0
- package/dist/agent-src/guidelines/agent-infra/layered-settings.md +317 -0
- package/dist/agent-src/guidelines/agent-infra/linked-projects-onboarding-gate.md +80 -0
- package/dist/agent-src/guidelines/agent-infra/mcp-request-signing.md +197 -0
- package/dist/agent-src/guidelines/agent-infra/memory-access.md +149 -0
- package/dist/agent-src/guidelines/agent-infra/mental-models.md +314 -0
- package/dist/agent-src/guidelines/agent-infra/minimal-safe-diff-mechanics.md +241 -0
- package/dist/agent-src/guidelines/agent-infra/missing-tool-handling.md +66 -0
- package/dist/agent-src/guidelines/agent-infra/model-recommendation.md +101 -0
- package/dist/agent-src/guidelines/agent-infra/naming.md +69 -0
- package/dist/agent-src/guidelines/agent-infra/notes-horizon-mechanics.md +90 -0
- package/dist/agent-src/guidelines/agent-infra/output-patterns.md +117 -0
- package/dist/agent-src/guidelines/agent-infra/recurring-criticism-mechanics.md +96 -0
- package/dist/agent-src/guidelines/agent-infra/reuse-verdict-mechanics.md +71 -0
- package/dist/agent-src/guidelines/agent-infra/review-routing-data-format.md +143 -0
- package/dist/agent-src/guidelines/agent-infra/roadmap-deferred-resolution-provenance.md +54 -0
- package/dist/agent-src/guidelines/agent-infra/roadmap-progress-mechanics.md +274 -0
- package/dist/agent-src/guidelines/agent-infra/role-contracts.md +209 -0
- package/dist/agent-src/guidelines/agent-infra/role-mode-router.md +89 -0
- package/dist/agent-src/guidelines/agent-infra/rule-body-migration-inventory.md +241 -0
- package/dist/agent-src/guidelines/agent-infra/rule-type-governance.md +73 -0
- package/dist/agent-src/guidelines/agent-infra/runtime-layer.md +89 -0
- package/dist/agent-src/guidelines/agent-infra/scqa-framework.md +526 -0
- package/dist/agent-src/guidelines/agent-infra/security-lint-containment.md +121 -0
- package/dist/agent-src/guidelines/agent-infra/self-improvement-pipeline.md +134 -0
- package/dist/agent-src/guidelines/agent-infra/simplicity-and-goal-demos.md +211 -0
- package/dist/agent-src/guidelines/agent-infra/six-hats.md +353 -0
- package/dist/agent-src/guidelines/agent-infra/size-and-scope.md +229 -0
- package/dist/agent-src/guidelines/agent-infra/skill-quality-checklist.md +157 -0
- package/dist/agent-src/guidelines/agent-infra/source-confidentiality-mechanics.md +109 -0
- package/dist/agent-src/guidelines/agent-infra/symptom-driven-harvest-loop.md +104 -0
- package/dist/agent-src/guidelines/agent-infra/systems-thinking.md +220 -0
- package/dist/agent-src/guidelines/agent-infra/tool-description-as-policy.md +35 -0
- package/dist/agent-src/guidelines/agent-infra/tool-integration.md +73 -0
- package/dist/agent-src/guidelines/agent-infra/traceability-field-mechanics.md +50 -0
- package/dist/agent-src/guidelines/agent-infra/untrusted-input-spotlighting.md +166 -0
- package/dist/agent-src/guidelines/agent-infra/verify-before-complete-demos.md +128 -0
- package/dist/agent-src/guidelines/augment-portability-patterns.md +70 -0
- package/dist/agent-src/guidelines/code-clarity.md +350 -0
- package/dist/agent-src/guidelines/component-oriented-and-oop-development.md +189 -0
- package/dist/agent-src/guidelines/cross-role-handoff.md +127 -0
- package/dist/agent-src/guidelines/design-antipatterns-triggers.json +18 -0
- package/dist/agent-src/guidelines/design-antipatterns.md +327 -0
- package/dist/agent-src/guidelines/design-asset-discipline.md +38 -0
- package/dist/agent-src/guidelines/design-canon.md +63 -0
- package/dist/agent-src/guidelines/design-fidelity-mechanics.md +293 -0
- package/dist/agent-src/guidelines/design-fidelity-routing.md +78 -0
- package/dist/agent-src/guidelines/design-handover-extraction.md +117 -0
- package/dist/agent-src/guidelines/design-modes.md +143 -0
- package/dist/agent-src/guidelines/design-reconciliation.md +172 -0
- package/dist/agent-src/guidelines/docs/readme-size-and-splitting.md +209 -0
- package/dist/agent-src/guidelines/e2e/playwright.md +363 -0
- package/dist/agent-src/guidelines/gtm-handoff.md +114 -0
- package/dist/agent-src/guidelines/monorepo-antipatterns.md +141 -0
- package/dist/agent-src/guidelines/php/api-design.md +115 -0
- package/dist/agent-src/guidelines/php/artisan-commands.md +81 -0
- package/dist/agent-src/guidelines/php/blade-ui.md +78 -0
- package/dist/agent-src/guidelines/php/controllers.md +90 -0
- package/dist/agent-src/guidelines/php/database.md +194 -0
- package/dist/agent-src/guidelines/php/eloquent.md +208 -0
- package/dist/agent-src/guidelines/php/flux.md +80 -0
- package/dist/agent-src/guidelines/php/general.md +207 -0
- package/dist/agent-src/guidelines/php/git.md +164 -0
- package/dist/agent-src/guidelines/php/jobs.md +111 -0
- package/dist/agent-src/guidelines/php/livewire.md +71 -0
- package/dist/agent-src/guidelines/php/logging.md +79 -0
- package/dist/agent-src/guidelines/php/naming.md +89 -0
- package/dist/agent-src/guidelines/php/patterns/dependency-injection.md +57 -0
- package/dist/agent-src/guidelines/php/patterns/dtos.md +199 -0
- package/dist/agent-src/guidelines/php/patterns/events.md +67 -0
- package/dist/agent-src/guidelines/php/patterns/factory.md +53 -0
- package/dist/agent-src/guidelines/php/patterns/pipelines.md +66 -0
- package/dist/agent-src/guidelines/php/patterns/policies.md +66 -0
- package/dist/agent-src/guidelines/php/patterns/repositories.md +122 -0
- package/dist/agent-src/guidelines/php/patterns/service-layer.md +64 -0
- package/dist/agent-src/guidelines/php/patterns/strategy.md +247 -0
- package/dist/agent-src/guidelines/php/patterns.md +28 -0
- package/dist/agent-src/guidelines/php/performance.md +92 -0
- package/dist/agent-src/guidelines/php/php-coding-patterns.md +80 -0
- package/dist/agent-src/guidelines/php/resources.md +100 -0
- package/dist/agent-src/guidelines/php/security.md +110 -0
- package/dist/agent-src/guidelines/php/sql.md +97 -0
- package/dist/agent-src/guidelines/php/validations.md +119 -0
- package/dist/agent-src/guidelines/php/websocket.md +100 -0
- package/dist/agent-src/guidelines/prompt-templates.md +189 -0
- package/dist/agent-src/guidelines/redundancy-taxonomy.md +208 -0
- package/dist/agent-src/guidelines/wing4-handoff.md +127 -0
- package/dist/agent-src/personas/README.md +1 -1
- package/dist/agent-src/personas/_template-specialist/persona.md +1 -1
- package/dist/agent-src/personas/product-owner.md +1 -1
- package/dist/agent-src/rules/active-remediation.md +1 -1
- package/dist/agent-src/rules/architecture.md +2 -2
- package/dist/agent-src/rules/artifact-drafting-protocol.md +1 -1
- package/dist/agent-src/rules/ask-when-uncertain.md +2 -2
- package/dist/agent-src/rules/brand-source-of-truth.md +9 -7
- package/dist/agent-src/rules/code-comment-discipline.md +2 -2
- package/dist/agent-src/rules/code-provenance.md +1 -1
- package/dist/agent-src/rules/content-quoting-floor.md +1 -1
- package/dist/agent-src/rules/context-hygiene.md +5 -5
- package/dist/agent-src/rules/cross-source-consistency.md +1 -1
- package/dist/agent-src/rules/design-fidelity.md +36 -46
- package/dist/agent-src/rules/direct-answers.md +2 -2
- package/dist/agent-src/rules/domain-adoption-policy.md +1 -1
- package/dist/agent-src/rules/evaluator-independence.md +1 -1
- package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +1 -1
- package/dist/agent-src/rules/icon-consistency.md +5 -1
- package/dist/agent-src/rules/improve-before-implement.md +1 -1
- package/dist/agent-src/rules/language-and-tone.md +3 -3
- package/dist/agent-src/rules/minimal-safe-diff.md +1 -1
- package/dist/agent-src/rules/notes-first-reasoning.md +2 -2
- package/dist/agent-src/rules/recurring-criticism.md +1 -1
- package/dist/agent-src/rules/roadmap-progress-sync.md +1 -1
- package/dist/agent-src/rules/role-mode-adherence.md +2 -2
- package/dist/agent-src/rules/security-sensitive-stop.md +1 -1
- package/dist/agent-src/rules/size-enforcement.md +1 -1
- package/dist/agent-src/rules/source-confidentiality.md +2 -2
- package/dist/agent-src/rules/think-before-action.md +1 -1
- package/dist/agent-src/rules/token-efficiency.md +7 -5
- package/dist/agent-src/rules/ui-audit-gate.md +3 -2
- package/dist/agent-src/rules/untrusted-input-defense.md +3 -3
- package/dist/agent-src/rules/user-interaction.md +31 -30
- package/dist/agent-src/skills/activation-design/SKILL.md +2 -2
- package/dist/agent-src/skills/adr-create/SKILL.md +5 -5
- package/dist/agent-src/skills/ai-council/SKILL.md +1 -1
- package/dist/agent-src/skills/ai-council/references/advanced-modes.md +1 -1
- package/dist/agent-src/skills/blade-ui/SKILL.md +1 -1
- package/dist/agent-src/skills/blast-radius-analyzer/SKILL.md +1 -1
- package/dist/agent-src/skills/brand-to-tokens/SKILL.md +24 -3
- package/dist/agent-src/skills/bug-analyzer/SKILL.md +1 -1
- package/dist/agent-src/skills/build-buy-partner/SKILL.md +1 -1
- package/dist/agent-src/skills/churn-prevention/SKILL.md +2 -2
- package/dist/agent-src/skills/code-refactoring/SKILL.md +3 -3
- package/dist/agent-src/skills/code-review/SKILL.md +3 -3
- package/dist/agent-src/skills/command-writing/SKILL.md +3 -3
- package/dist/agent-src/skills/comp-banding/SKILL.md +1 -1
- package/dist/agent-src/skills/competitive-moat-analysis/SKILL.md +1 -1
- package/dist/agent-src/skills/competitive-positioning/SKILL.md +2 -2
- package/dist/agent-src/skills/complexity-first-planning/SKILL.md +1 -1
- package/dist/agent-src/skills/condense-memory/SKILL.md +1 -1
- package/dist/agent-src/skills/content-funnel-design/SKILL.md +2 -2
- package/dist/agent-src/skills/contracts-cognition/SKILL.md +1 -1
- package/dist/agent-src/skills/copilot-agents-optimization/SKILL.md +2 -2
- package/dist/agent-src/skills/corpus-grounding/SKILL.md +2 -2
- package/dist/agent-src/skills/customer-research/SKILL.md +2 -2
- package/dist/agent-src/skills/dashboard-design/SKILL.md +1 -1
- package/dist/agent-src/skills/data-handling-judgment/SKILL.md +1 -1
- package/dist/agent-src/skills/deal-qualification-meddic/SKILL.md +2 -2
- package/dist/agent-src/skills/decision-record/SKILL.md +3 -3
- package/dist/agent-src/skills/decision-review/SKILL.md +8 -8
- package/dist/agent-src/skills/deep-reading-analyst/SKILL.md +22 -22
- package/dist/agent-src/skills/design-intelligence/SKILL.md +4 -4
- package/dist/agent-src/skills/design-intelligence/references/context-and-registers.md +2 -2
- package/dist/agent-src/skills/design-review/SKILL.md +4 -4
- package/dist/agent-src/skills/design-system-capture/references/design-system-json.md +20 -1
- package/dist/agent-src/skills/design-tokens/SKILL.md +17 -2
- package/dist/agent-src/skills/design-variations/SKILL.md +2 -2
- package/dist/agent-src/skills/developer-like-execution/SKILL.md +2 -2
- package/dist/agent-src/skills/discovery-interview/SKILL.md +2 -2
- package/dist/agent-src/skills/doc-coauthoring/SKILL.md +3 -3
- package/dist/agent-src/skills/editorial-calendar/SKILL.md +2 -2
- package/dist/agent-src/skills/error-handling-patterns/SKILL.md +9 -0
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +44 -1
- package/dist/agent-src/skills/existing-ui-audit/references/anti-slop-cross-reference.md +2 -2
- package/dist/agent-src/skills/expansion-playbook/SKILL.md +2 -2
- package/dist/agent-src/skills/experiment-loop/SKILL.md +1 -1
- package/dist/agent-src/skills/experiment-loop/references/protocol.md +1 -1
- package/dist/agent-src/skills/fe-design/SKILL.md +3 -3
- package/dist/agent-src/skills/fe-design/references/design-patterns.md +1 -1
- package/dist/agent-src/skills/fe-design/references/design-read-and-memory.md +3 -3
- package/dist/agent-src/skills/fe-design/references/source-led-port.md +1 -1
- package/dist/agent-src/skills/feature-planning/SKILL.md +1 -1
- package/dist/agent-src/skills/flux/SKILL.md +1 -1
- package/dist/agent-src/skills/forecast-accuracy/SKILL.md +2 -2
- package/dist/agent-src/skills/forecasting/SKILL.md +2 -2
- package/dist/agent-src/skills/fundraising-narrative/SKILL.md +2 -2
- package/dist/agent-src/skills/funnel-analysis/SKILL.md +2 -2
- package/dist/agent-src/skills/gtm-launch/SKILL.md +2 -2
- package/dist/agent-src/skills/hiring-loop-design/SKILL.md +1 -1
- package/dist/agent-src/skills/html-deck/SKILL.md +5 -5
- package/dist/agent-src/skills/humanizer/SKILL.md +1 -1
- package/dist/agent-src/skills/humanizer/data/patterns.md +1 -1
- package/dist/agent-src/skills/iconography/SKILL.md +3 -3
- package/dist/agent-src/skills/judge-synthesis/SKILL.md +1 -1
- package/dist/agent-src/skills/laravel-api-endpoint/SKILL.md +2 -2
- package/dist/agent-src/skills/launch-readiness/SKILL.md +3 -3
- package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +6 -6
- package/dist/agent-src/skills/livewire/SKILL.md +1 -1
- package/dist/agent-src/skills/market-entry-analysis/SKILL.md +1 -1
- package/dist/agent-src/skills/mcp-builder/SKILL.md +1 -1
- package/dist/agent-src/skills/memory-consolidation/SKILL.md +3 -3
- package/dist/agent-src/skills/messaging-architecture/SKILL.md +2 -2
- package/dist/agent-src/skills/monorepo-workspace/SKILL.md +1 -1
- package/dist/agent-src/skills/onboarding-design/SKILL.md +2 -2
- package/dist/agent-src/skills/onboarding-program/SKILL.md +1 -1
- package/dist/agent-src/skills/one-on-one-cadence/SKILL.md +1 -1
- package/dist/agent-src/skills/org-design/SKILL.md +1 -1
- package/dist/agent-src/skills/overbuild-review-lens/SKILL.md +3 -3
- package/dist/agent-src/skills/override-management/SKILL.md +1 -1
- package/dist/agent-src/skills/perf-feedback-craft/SKILL.md +1 -1
- package/dist/agent-src/skills/persona-writing/SKILL.md +1 -1
- package/dist/agent-src/skills/php-coder/SKILL.md +1 -1
- package/dist/agent-src/skills/pipeline-strategy/SKILL.md +2 -2
- package/dist/agent-src/skills/playwright-testing/SKILL.md +3 -3
- package/dist/agent-src/skills/po-discovery/SKILL.md +1 -1
- package/dist/agent-src/skills/positioning-strategy/SKILL.md +2 -2
- package/dist/agent-src/skills/privacy-review/SKILL.md +1 -1
- package/dist/agent-src/skills/prompt-optimizer/SKILL.md +3 -3
- package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
- package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +2 -2
- package/dist/agent-src/skills/receiving-code-review/SKILL.md +1 -1
- package/dist/agent-src/skills/refine-ticket/SKILL.md +2 -2
- package/dist/agent-src/skills/release-comms/SKILL.md +2 -2
- package/dist/agent-src/skills/retention-loops/SKILL.md +2 -2
- package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
- package/dist/agent-src/skills/roadmap-management/SKILL.md +1 -1
- package/dist/agent-src/skills/roadmap-management/references/archival.md +1 -1
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +5 -5
- package/dist/agent-src/skills/rule-writing/SKILL.md +6 -6
- package/dist/agent-src/skills/runway-cognition/SKILL.md +2 -2
- package/dist/agent-src/skills/scenario-modeling/SKILL.md +2 -2
- package/dist/agent-src/skills/skill-writing/SKILL.md +2 -2
- package/dist/agent-src/skills/skill-writing/references/procedure.md +1 -1
- package/dist/agent-src/skills/skill-writing/references/section-patterns.md +3 -3
- package/dist/agent-src/skills/spreadsheet-authoring/SKILL.md +1 -1
- package/dist/agent-src/skills/stakeholder-tradeoff/SKILL.md +3 -3
- package/dist/agent-src/skills/subagent-orchestration/SKILL.md +1 -1
- package/dist/agent-src/skills/supply-chain-intake/SKILL.md +1 -1
- package/dist/agent-src/skills/systematic-debugging/SKILL.md +2 -2
- package/dist/agent-src/skills/tailwind-engineer/SKILL.md +11 -5
- package/dist/agent-src/skills/throughput-vs-morale-tradeoff/SKILL.md +1 -1
- package/dist/agent-src/skills/token-optimizer/SKILL.md +1 -1
- package/dist/agent-src/skills/typography-system/SKILL.md +2 -2
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +28 -8
- package/dist/agent-src/skills/unit-economics-modeling/SKILL.md +2 -2
- package/dist/agent-src/skills/upstream-contribute/SKILL.md +1 -1
- package/dist/agent-src/skills/validate-feature-fit/SKILL.md +2 -2
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +2 -2
- package/dist/agent-src/skills/vision-articulation/SKILL.md +1 -1
- package/dist/agent-src/skills/voc-extract/SKILL.md +2 -2
- package/dist/agent-src/skills/voice-and-tone-design/SKILL.md +2 -2
- package/dist/agent-src/skills/wireframe/SKILL.md +1 -1
- package/dist/agent-src/skills/workspace-link/SKILL.md +1 -1
- package/dist/agent-src/templates/agent-settings.md +6 -6
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/contexts/knowledge-pages.md +2 -3
- package/dist/agent-src/templates/copilot-instructions.md +1 -1
- package/dist/agent-src/templates/roadmaps.md +1 -1
- package/dist/agent-src/templates/scripts/README.md +2 -2
- package/dist/agent-src/user-types/_template/user-type.md +1 -1
- package/dist/cli-delegate/check_update_banner.js +12 -1
- package/dist/cli-delegate/{chunk-NLP54U3J.js → chunk-2XY7ILBT.js} +13 -1
- package/dist/cli-delegate/{chunk-IAI3XL43.js → chunk-3FKR64R5.js} +22 -6
- package/dist/cli-delegate/{chunk-J3RFNKG4.js → chunk-55ACLDUE.js} +2 -2
- package/dist/cli-delegate/{chunk-PKOBQADP.js → chunk-57PN4GYJ.js} +1 -1
- package/dist/cli-delegate/{chunk-KCNTUSPI.js → chunk-AK6HODNQ.js} +4 -4
- package/dist/cli-delegate/{chunk-2FTMENJL.js → chunk-GYC3VRYN.js} +1 -1
- package/dist/cli-delegate/{chunk-LWTYTX6F.js → chunk-H32DGUJH.js} +15 -84
- package/dist/cli-delegate/{chunk-6RJA2F5A.js → chunk-IVBPRCQO.js} +1 -1
- package/dist/cli-delegate/chunk-NUHLI2RX.js +80 -0
- package/dist/cli-delegate/{chunk-TYSY33MD.js → chunk-QJWAUMJW.js} +12 -2
- package/dist/cli-delegate/{chunk-2KKXJW25.js → chunk-S3VFXMTM.js} +1 -1
- package/dist/cli-delegate/{chunk-I6RHFQEG.js → chunk-YUM5KURG.js} +17 -1
- package/dist/cli-delegate/cmd_analyze_session.js +1 -1
- package/dist/cli-delegate/cmd_brand_status.js +1 -1
- package/dist/cli-delegate/cmd_conformance.js +834 -275
- package/dist/cli-delegate/cmd_doctor.js +3 -3
- package/dist/cli-delegate/cmd_explain.js +5 -3
- package/dist/cli-delegate/cmd_export.js +4 -4
- package/dist/cli-delegate/cmd_handoff.js +6 -6
- package/dist/cli-delegate/cmd_mcp_available.js +1 -1
- package/dist/cli-delegate/cmd_memory_get.js +1 -1
- package/dist/cli-delegate/cmd_migrate.js +2 -2
- package/dist/cli-delegate/cmd_packs_active.js +3 -2
- package/dist/cli-delegate/cmd_prune.js +4 -4
- package/dist/cli-delegate/cmd_route_audit.js +3 -3
- package/dist/cli-delegate/cmd_route_explain.js +1 -1
- package/dist/cli-delegate/cmd_session_recycle.js +3 -3
- package/dist/cli-delegate/cmd_settings_get.js +15 -9
- package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
- package/dist/cli-delegate/cmd_settings_set.js +54 -11
- package/dist/cli-delegate/cmd_sync.js +4 -4
- package/dist/cli-delegate/cmd_uninstall.js +4 -4
- package/dist/cli-delegate/cmd_update.js +1 -1
- package/dist/cli-delegate/cmd_upgrade.js +1 -1
- package/dist/cli-delegate/cmd_validate.js +4 -4
- package/dist/cli-delegate/cmd_versions.js +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +25 -78
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -3
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +5 -7
- package/dist/discovery/trust-report.md +2 -2
- package/dist/discovery/workspaces.json +4 -6
- package/dist/hooks/dispatch.js +9684 -9304
- package/dist/install/install.mjs +36 -8
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +2147 -1470
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/agent_settings.js +73 -0
- package/dist/scripts/_lib/agent_src.js +20 -0
- package/dist/scripts/_lib/guidelines_lane.js +158 -0
- package/dist/scripts/_lib/installed_lock.js +1 -1
- package/dist/scripts/condense.js +2 -5
- package/dist/server/io/yamlIO.js +175 -17
- package/dist/server/schemas/settings.js +18 -4
- package/dist/shared/settingsSurface.js +6 -1
- package/docs/contracts/settings-classes.md +18 -9
- package/docs/guidelines/abstraction-thresholds.md +35 -0
- package/docs/guidelines/agent-infra/active-remediation-mechanics.md +3 -3
- package/docs/guidelines/agent-infra/false-green.md +2 -2
- package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
- package/docs/guidelines/agent-infra/skill-quality-checklist.md +1 -1
- package/docs/guidelines/design-fidelity-mechanics.md +4 -0
- package/docs/guidelines/design-fidelity-routing.md +78 -0
- package/docs/guidelines/design-reconciliation.md +172 -0
- package/docs/guidelines/gtm-handoff.md +2 -2
- package/docs/guidelines/wing4-handoff.md +2 -2
- package/package.json +7 -3
- package/src/config/agent-settings.template.yml +55 -8
- package/src/config/ci-local-parity.yml +34 -0
- package/src/config/continuity-surface.json +11 -32
- package/src/config/gate-coverage.yml +31 -8
- package/src/config/gate-reachability-exemptions.json +1 -0
- package/src/config/gate-violation-baselines.json +3 -3
- package/src/config/hook-token-budget.json +1 -1
- package/src/config/host-injection-effect.json +2 -2
- package/src/config/pack-size-budget.json +55 -4
- package/src/config/platform-anchor.json +47 -0
- package/src/config/preamble-payload-budget.json +12 -8
- package/src/config/preamble-payload-exceptions.json +28 -0
- package/src/config/publish-surface.json +4 -2
- package/src/config/ratification-policy.json +7 -0
- package/src/config/rule-stub-ceilings.json +16 -9
- package/src/scripts/_cli/cmd_settings_get.ts +22 -7
- package/src/scripts/_dispatch.bash +3 -1
- package/src/scripts/_lib/agent_settings.ts +85 -0
- package/src/scripts/_lib/agent_src.ts +21 -0
- package/src/scripts/_lib/artifact_maturity.ts +242 -0
- package/src/scripts/_lib/base_ref_payload.ts +315 -0
- package/src/scripts/_lib/conformance_report.ts +403 -0
- package/src/scripts/_lib/continuity_writer.ts +72 -13
- package/src/scripts/_lib/design_system_import.ts +20 -0
- package/src/scripts/_lib/design_tolerance.ts +281 -0
- package/src/scripts/_lib/dropped_decision.ts +142 -0
- package/src/scripts/_lib/guidelines_lane.ts +164 -0
- package/src/scripts/_lib/installed_lock.ts +1 -1
- package/src/scripts/_lib/measured_payload_ceiling.ts +424 -0
- package/src/scripts/_lib/obligation_frequency.ts +2 -3
- package/src/scripts/_lib/payload_catalogue_completeness.ts +211 -0
- package/src/scripts/_lib/platform_anchor.ts +1053 -0
- package/src/scripts/_lib/ratification_artifact.ts +278 -0
- package/src/scripts/_lib/release_findings_ingest.ts +324 -0
- package/src/scripts/_lib/release_tag_dispatch.ts +63 -0
- package/src/scripts/_lib/review_baseline.ts +254 -0
- package/src/scripts/_lib/review_skipped_record.ts +61 -1
- package/src/scripts/_lib/security_lint.ts +23 -2
- package/src/scripts/_lib/self_repair.ts +21 -0
- package/src/scripts/_lib/session_index_trust.ts +42 -1
- package/src/scripts/_lib/standing_bound_ratchet.ts +267 -88
- package/src/scripts/_lib/tolerance_shadow.ts +177 -0
- package/src/scripts/_lib/turn_end_refusals.ts +51 -4
- package/src/scripts/ai_council/redact_low_impact_entry.ts +8 -0
- package/src/scripts/autonomy_friction_traffic.ts +379 -0
- package/src/scripts/check_beta_review_markers.ts +35 -4
- package/src/scripts/check_finding_dispositions.ts +167 -16
- package/src/scripts/check_held_object_arrivals.ts +381 -0
- package/src/scripts/check_kernel_edit_ratified.ts +462 -0
- package/src/scripts/check_loss_class_declared.ts +793 -46
- package/src/scripts/check_platform_anchor.ts +390 -0
- package/src/scripts/check_preamble_payload_budget.ts +672 -107
- package/src/scripts/check_projected_rule_routes.ts +395 -0
- package/src/scripts/check_release_published.ts +1 -1
- package/src/scripts/check_reply_consistency.ts +86 -17
- package/src/scripts/code_graph/cli.ts +6 -0
- package/src/scripts/condense.ts +2 -6
- package/src/scripts/generate_host_cost_table.ts +354 -0
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +74 -30
- package/src/scripts/hooks/block_kernel_rule_writes.ts +12 -2
- package/src/scripts/hooks/category_a.ts +1 -1
- package/src/scripts/hooks/chain_nudge_hook.ts +311 -25
- package/src/scripts/hooks/concern_registry.ts +2 -0
- package/src/scripts/hooks/end_review_nudge_hook.ts +101 -21
- package/src/scripts/hooks/review_baseline_hook.ts +130 -0
- package/src/scripts/hooks/session_eol_hook.ts +68 -154
- package/src/scripts/hooks/source_first_gate_hook.ts +12 -0
- package/src/scripts/hooks/turn_end_gate_hook.ts +232 -14
- package/src/scripts/hooks/ui_route_nudge_hook.ts +52 -15
- package/src/scripts/hooks_doctor.ts +4 -1
- package/src/scripts/hot_context_hook.ts +41 -401
- package/src/scripts/install.ts +1 -1
- package/src/scripts/interruption_report.ts +8 -2
- package/src/scripts/janitor.ts +8 -1
- package/src/scripts/lint_evidence_artifacts.ts +1 -0
- package/src/scripts/lint_knowledge_scale.ts +0 -26
- package/src/scripts/measure_turn_end_gate.ts +302 -5
- package/src/scripts/memory_lookup.ts +9 -9
- package/src/scripts/release.ts +52 -64
- package/src/scripts/release_drill.ts +193 -14
- package/src/scripts/release_env.ts +1 -1
- package/src/scripts/release_publication.ts +1 -1
- package/src/scripts/report_held_object_arrivals.ts +456 -0
- package/src/scripts/report_standing_payload_by_host.ts +7 -7
- package/src/scripts/session_memory_index.ts +5 -0
- package/src/scripts/sync_agent_settings.ts +394 -12
- package/src/server/io/yamlIO.ts +175 -17
- package/src/server/schemas/settings.ts +25 -5
- package/src/shared/settingsSurface.ts +13 -2
- package/src/templates/compact-instructions.md +8 -3
- package/dist/agent-src/commands/chat-history/import.md +0 -170
- package/dist/agent-src/commands/chat-history.md +0 -63
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ratification artifact — ADR-268 § 4's control, in one reader.
|
|
3
|
+
*
|
|
4
|
+
* ADR-268 § 4 permits an agent to edit kernel rules, governance hooks and
|
|
5
|
+
* authority schemas inside an authorised mission, and forbids it to ratify its
|
|
6
|
+
* own increase in power:
|
|
7
|
+
*
|
|
8
|
+
* ```
|
|
9
|
+
* AN AGENT MAY MODIFY ITS CONSTITUTION. IT MAY NOT RATIFY ITS OWN INCREASE IN POWER.
|
|
10
|
+
* THE PARTY GAINING THE AUTHORITY IS NEVER THE PARTY RECORDING THE RATIFICATION.
|
|
11
|
+
* PROVIDER DIVERSITY IS REQUIRED WHERE TWO PROVIDERS ARE CONFIGURED.
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* That sentence is the whole reason this module exists as a pure reader with
|
|
15
|
+
* no filesystem and no network: the gate that reds a PR
|
|
16
|
+
* (`check_kernel_edit_ratified`) and the tests that prove it reds must decide
|
|
17
|
+
* from the same code, or the fixture proves a second implementation rather
|
|
18
|
+
* than the shipped one.
|
|
19
|
+
*
|
|
20
|
+
* Why `reviewed_by` is checked against BOTH producer fields.
|
|
21
|
+
* `road-to-typed-grants-that-persist` Phase 5.1 names one fixture — an
|
|
22
|
+
* artifact whose `proposed_by` equals its `reviewed_by` is rejected. The Iron
|
|
23
|
+
* Law above is broader than that fixture: the party gaining the authority is
|
|
24
|
+
* the party that proposed the expansion AND the party that implemented it, and
|
|
25
|
+
* an artifact reviewed by its own implementer is the same defect wearing the
|
|
26
|
+
* other field's name. Both are rejected, and this paragraph is why the code is
|
|
27
|
+
* wider than the step that asked for it.
|
|
28
|
+
*
|
|
29
|
+
* What this module does NOT decide: whether a diff is authority-EXPANDING.
|
|
30
|
+
* That is a judgement over rule prose, not a property of the artifact, and
|
|
31
|
+
* ADR-268 § 4 makes the artifact required for the expanding case only.
|
|
32
|
+
* `check_kernel_edit_ratified` requires the artifact for every kernel-rule
|
|
33
|
+
* diff instead — a strictly stronger and decidable rule — and says so in its
|
|
34
|
+
* own header rather than pretending to classify.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
import { readAdrFrontmatter, type AdrFrontmatter } from './adr_frontmatter.js';
|
|
38
|
+
|
|
39
|
+
/** Where a ratification artifact lives. One directory, so the gate can find it. */
|
|
40
|
+
export const RATIFICATION_DIR = 'agents/evidence/ratifications';
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The verdict vocabulary — closed, because an open one is a free-text field
|
|
44
|
+
* that always reads as approval to a grep.
|
|
45
|
+
*/
|
|
46
|
+
export const RATIFICATION_VERDICTS = [
|
|
47
|
+
'ratified',
|
|
48
|
+
'confirmed-non-expanding',
|
|
49
|
+
'refused',
|
|
50
|
+
'non-convergent',
|
|
51
|
+
] as const;
|
|
52
|
+
export type RatificationVerdict = (typeof RATIFICATION_VERDICTS)[number];
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The two verdicts that let a diff land.
|
|
56
|
+
*
|
|
57
|
+
* `confirmed-non-expanding` exists because the gate demands an artifact for
|
|
58
|
+
* EVERY kernel and governance-hook diff, including a typo fix. Calling that a
|
|
59
|
+
* ratification of an authority expansion would be false, and a vocabulary that
|
|
60
|
+
* forces a false label is a vocabulary people route around. Adopted from the
|
|
61
|
+
* round-1 review, which named the pressure this relieves.
|
|
62
|
+
*/
|
|
63
|
+
export const PASSING_VERDICTS: ReadonlySet<string> = new Set([
|
|
64
|
+
'ratified',
|
|
65
|
+
'confirmed-non-expanding',
|
|
66
|
+
]);
|
|
67
|
+
|
|
68
|
+
/** The six fields Phase 5.1 names, all required. */
|
|
69
|
+
export const RATIFICATION_FIELDS = [
|
|
70
|
+
'proposed_by',
|
|
71
|
+
'implemented_by',
|
|
72
|
+
'reviewed_by',
|
|
73
|
+
'providers',
|
|
74
|
+
'verdict',
|
|
75
|
+
'effective_after',
|
|
76
|
+
] as const;
|
|
77
|
+
|
|
78
|
+
export interface RatificationArtifact {
|
|
79
|
+
proposed_by: string;
|
|
80
|
+
implemented_by: string;
|
|
81
|
+
reviewed_by: string;
|
|
82
|
+
/** Provider ids consulted, in source order. Diversity is counted over this. */
|
|
83
|
+
providers: string[];
|
|
84
|
+
verdict: RatificationVerdict;
|
|
85
|
+
/** `merge`, or an ISO-8601 instant. Never a bare "later". */
|
|
86
|
+
effective_after: string;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface RatificationProblem {
|
|
90
|
+
/** Stable code, so a test asserts the reason rather than the wording. */
|
|
91
|
+
code:
|
|
92
|
+
| 'no-frontmatter'
|
|
93
|
+
| 'missing-field'
|
|
94
|
+
| 'unknown-verdict'
|
|
95
|
+
| 'self-ratified'
|
|
96
|
+
| 'no-providers'
|
|
97
|
+
| 'diversity-required'
|
|
98
|
+
| 'diversity-unverifiable'
|
|
99
|
+
| 'bad-effective-after';
|
|
100
|
+
message: string;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface RatificationReading {
|
|
104
|
+
artifact: RatificationArtifact | null;
|
|
105
|
+
problems: RatificationProblem[];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** `merge`, or an ISO-8601 instant with a timezone. */
|
|
109
|
+
const EFFECTIVE_AFTER_RE =
|
|
110
|
+
/^(merge|\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2}))$/;
|
|
111
|
+
|
|
112
|
+
function scalarOf(fm: AdrFrontmatter, key: string): string | null {
|
|
113
|
+
const raw = fm.scalars[key];
|
|
114
|
+
if (typeof raw !== 'string') {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
const trimmed = raw.trim();
|
|
118
|
+
return trimmed === '' ? null : trimmed;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Read `providers` in either shape the frontmatter parser can produce — a YAML
|
|
123
|
+
* list (nested) or an inline `[a, b]` scalar. Accepting both is not laxity:
|
|
124
|
+
* the ADR frontmatter corpus already carries both shapes for `basis`, and a
|
|
125
|
+
* reader that took only one would reject a correctly-authored artifact.
|
|
126
|
+
*/
|
|
127
|
+
export function readProviders(fm: AdrFrontmatter): string[] {
|
|
128
|
+
const nested = fm.nested['providers'];
|
|
129
|
+
if (Array.isArray(nested)) {
|
|
130
|
+
return nested.map((p) => String(p).trim()).filter((p) => p !== '');
|
|
131
|
+
}
|
|
132
|
+
const scalar = scalarOf(fm, 'providers');
|
|
133
|
+
if (scalar === null) {
|
|
134
|
+
return [];
|
|
135
|
+
}
|
|
136
|
+
return scalar
|
|
137
|
+
.replace(/^\[|\]$/g, '')
|
|
138
|
+
.split(',')
|
|
139
|
+
.map((p) => p.trim().replace(/^["']|["']$/g, ''))
|
|
140
|
+
.filter((p) => p !== '');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Validate one artifact's text.
|
|
145
|
+
*
|
|
146
|
+
* `configuredProviders` is the count `agent-config council:status` reports.
|
|
147
|
+
* Pass `null` when it could not be established — the diversity rule then does
|
|
148
|
+
* not fire, and the caller says so, because an unmeasured count is not
|
|
149
|
+
* evidence that diversity was unavailable.
|
|
150
|
+
*/
|
|
151
|
+
export function readRatification(
|
|
152
|
+
text: string,
|
|
153
|
+
configuredProviders: number | null,
|
|
154
|
+
): RatificationReading {
|
|
155
|
+
const problems: RatificationProblem[] = [];
|
|
156
|
+
const fm = readAdrFrontmatter(text);
|
|
157
|
+
if (fm === null) {
|
|
158
|
+
return {
|
|
159
|
+
artifact: null,
|
|
160
|
+
problems: [{ code: 'no-frontmatter', message: 'no YAML frontmatter block' }],
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const providers = readProviders(fm);
|
|
165
|
+
const values: Record<string, string | null> = {};
|
|
166
|
+
for (const field of RATIFICATION_FIELDS) {
|
|
167
|
+
if (field === 'providers') {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
values[field] = scalarOf(fm, field);
|
|
171
|
+
if (values[field] === null) {
|
|
172
|
+
problems.push({ code: 'missing-field', message: `missing or empty \`${field}:\`` });
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (providers.length === 0) {
|
|
176
|
+
problems.push({ code: 'no-providers', message: 'missing or empty `providers:`' });
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const verdict = values['verdict'] ?? null;
|
|
180
|
+
if (verdict !== null && !(RATIFICATION_VERDICTS as readonly string[]).includes(verdict)) {
|
|
181
|
+
problems.push({
|
|
182
|
+
code: 'unknown-verdict',
|
|
183
|
+
message: `verdict \`${verdict}\` is not one of ${RATIFICATION_VERDICTS.join(', ')}`,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const effective = values['effective_after'] ?? null;
|
|
188
|
+
if (effective !== null && !EFFECTIVE_AFTER_RE.test(effective)) {
|
|
189
|
+
problems.push({
|
|
190
|
+
code: 'bad-effective-after',
|
|
191
|
+
message: `effective_after \`${effective}\` is neither \`merge\` nor an ISO-8601 instant`,
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// The Iron Law. Checked against both producer fields — see the header.
|
|
196
|
+
const reviewer = values['reviewed_by'];
|
|
197
|
+
if (reviewer !== null) {
|
|
198
|
+
for (const producerField of ['proposed_by', 'implemented_by'] as const) {
|
|
199
|
+
const producer = values[producerField];
|
|
200
|
+
if (producer !== null && producer === reviewer) {
|
|
201
|
+
problems.push({
|
|
202
|
+
code: 'self-ratified',
|
|
203
|
+
message:
|
|
204
|
+
`\`${producerField}\` equals \`reviewed_by\` (${reviewer}) — ` +
|
|
205
|
+
'the party gaining the authority may not record the ratification (ADR-268 section 4)',
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Diversity, against the REQUIRED count.
|
|
212
|
+
//
|
|
213
|
+
// Round 1 refused the previous shape: the count came from the user-global
|
|
214
|
+
// council config, which is absent on a CI runner, so the rule silently did
|
|
215
|
+
// not fire there. `null` now means the required count could not be
|
|
216
|
+
// established, and that is a REFUSAL rather than a skip — a control that
|
|
217
|
+
// passes when it cannot measure is advisory.
|
|
218
|
+
if (configuredProviders === null) {
|
|
219
|
+
problems.push({
|
|
220
|
+
code: 'diversity-unverifiable',
|
|
221
|
+
message:
|
|
222
|
+
'the required provider count could not be read, so diversity is unverifiable — ' +
|
|
223
|
+
'a control that cannot measure fails closed (src/config/ratification-policy.json)',
|
|
224
|
+
});
|
|
225
|
+
} else if (configuredProviders >= 2) {
|
|
226
|
+
const distinct = new Set(providers);
|
|
227
|
+
if (distinct.size < configuredProviders) {
|
|
228
|
+
problems.push({
|
|
229
|
+
code: 'diversity-required',
|
|
230
|
+
message:
|
|
231
|
+
`${configuredProviders} distinct providers are required; ` +
|
|
232
|
+
`the artifact names ${distinct.size} (${providers.join(', ') || 'none'})`,
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (problems.length > 0) {
|
|
238
|
+
return { artifact: null, problems };
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return {
|
|
242
|
+
artifact: {
|
|
243
|
+
proposed_by: values['proposed_by'] as string,
|
|
244
|
+
implemented_by: values['implemented_by'] as string,
|
|
245
|
+
reviewed_by: reviewer as string,
|
|
246
|
+
providers,
|
|
247
|
+
verdict: verdict as RatificationVerdict,
|
|
248
|
+
effective_after: effective as string,
|
|
249
|
+
},
|
|
250
|
+
problems: [],
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/** True when the artifact parses and carries a verdict that lets the diff land. */
|
|
255
|
+
export function isRatified(reading: RatificationReading): boolean {
|
|
256
|
+
return reading.artifact !== null && PASSING_VERDICTS.has(reading.artifact.verdict);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* The required distinct-provider count, from the repository's own policy file.
|
|
261
|
+
*
|
|
262
|
+
* Returns `null` when the file is missing or unparseable, and the caller turns
|
|
263
|
+
* that into a refusal — never a skip. Reading the policy from the repository
|
|
264
|
+
* rather than from the user-global council config is the round-1 fix: a runner
|
|
265
|
+
* has the repository and does not have the operator's home directory.
|
|
266
|
+
*/
|
|
267
|
+
export function readRequiredProviders(policyText: string | null): number | null {
|
|
268
|
+
if (policyText === null) {
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
try {
|
|
272
|
+
const parsed = JSON.parse(policyText) as { required_providers?: unknown };
|
|
273
|
+
const n = parsed.required_providers;
|
|
274
|
+
return typeof n === 'number' && Number.isInteger(n) && n >= 1 ? n : null;
|
|
275
|
+
} catch {
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The release's side of the findings-ledger contract: verification, not
|
|
3
|
+
* production.
|
|
4
|
+
*
|
|
5
|
+
* WHY THE CONTRACT EXISTS. The findings ledger is the durable record a release
|
|
6
|
+
* makes about what its own review found, and `check_finding_dispositions`
|
|
7
|
+
* treats an absent one for a SHIPPED version as a failure — repo-wide, because
|
|
8
|
+
* the same check runs on every pull request. Producing it was documented and
|
|
9
|
+
* unowned: the self-review workflow uploaded an artifact and its own comment
|
|
10
|
+
* said a human should run `--ingest`. Nobody did, so the ledger went missing
|
|
11
|
+
* once per release, six times between 14.19.0 and 15.0.0, and each absence was
|
|
12
|
+
* cleared by whoever happened to be pushing an unrelated change.
|
|
13
|
+
*
|
|
14
|
+
* WHY THE INGEST IS NOT HERE. Two review rounds established that no placement
|
|
15
|
+
* inside `release.ts` works. `finding-dispositions` runs on the release PR and
|
|
16
|
+
* reds while the ledger lacks a finding the review reported, so a step that
|
|
17
|
+
* produced the ledger after the check wait could never run — the wait had
|
|
18
|
+
* already died on that red check — and a step that produced it before the wait
|
|
19
|
+
* pushed a commit the wait then had to redo, on a head whose checks had not
|
|
20
|
+
* started. The owner's decision on 2026-09-11 was to move the ingest into the
|
|
21
|
+
* workflow that already holds the artifact, which is the one place where the
|
|
22
|
+
* ledger can exist before any gate looks for it.
|
|
23
|
+
*
|
|
24
|
+
* WHY THE PUSH NEEDS A PAT. A third review round found that the move alone did
|
|
25
|
+
* not fix the ordering, it relocated it: the ingest job is a check run of the
|
|
26
|
+
* same `pull_request` event, so its push lands inside the release's own check
|
|
27
|
+
* wait — and a push authenticated with GITHUB_TOKEN creates no run, leaving a
|
|
28
|
+
* head with zero checks against a protection that requires one. The job pushes
|
|
29
|
+
* with `RELEASE_PR_TOKEN` instead, the pattern `release.yml` already uses, so
|
|
30
|
+
* the push produces the checks the wait is waiting for. Without that secret the
|
|
31
|
+
* job declines to push at all rather than produce the deadlock, and the absence
|
|
32
|
+
* arrives here as a missing ledger with the cause named.
|
|
33
|
+
*
|
|
34
|
+
* WHAT IS LEFT HERE. Two questions and a stop for each: is the ledger on the
|
|
35
|
+
* REMOTE branch, and does the disposition gate pass. Neither is repaired by
|
|
36
|
+
* the release — filling a disposition states what the release ships, with a
|
|
37
|
+
* rationale and a named verifier, and no automation writes one.
|
|
38
|
+
*/
|
|
39
|
+
import * as fs from 'node:fs';
|
|
40
|
+
import * as path from 'node:path';
|
|
41
|
+
|
|
42
|
+
import { isBlocking, parse_ledger } from '../check_finding_dispositions.js';
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
/** Where a release's ledger lives, relative to the repository root. */
|
|
46
|
+
export function ledgerRelPath(version: string): string {
|
|
47
|
+
return `agents/evidence/release-findings/${version}.json`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The workflow that produces and commits the ledger, named so a message can
|
|
52
|
+
* point the operator at the right run log.
|
|
53
|
+
*
|
|
54
|
+
* A rename there without one here is caught by
|
|
55
|
+
* `release_findings_ingest.test.ts`, which reads the workflow file rather than
|
|
56
|
+
* trusting this string.
|
|
57
|
+
*/
|
|
58
|
+
export const FINDINGS_WORKFLOW = 'self-review-gate.yml';
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Argv proving the ledger is on the REMOTE branch — the only ref that answers
|
|
62
|
+
* the question the release is asking.
|
|
63
|
+
*
|
|
64
|
+
* Three refs give three different answers and only one is right. The working
|
|
65
|
+
* tree says "a file exists here", which a by-hand ingest also satisfies. The
|
|
66
|
+
* LOCAL branch ref says "a commit here carries it", which a commit that failed
|
|
67
|
+
* to push has already made true — so probing it answers identically to the
|
|
68
|
+
* filesystem in exactly the case the probe exists for, which is the defect a
|
|
69
|
+
* second review round caught in the first attempt at this fix. The
|
|
70
|
+
* remote-tracking ref is the one that goes false when a push fails, and the
|
|
71
|
+
* merge reads the remote.
|
|
72
|
+
*
|
|
73
|
+
* `remote` is a parameter rather than a constant so a fork or a mirror is not
|
|
74
|
+
* silently assumed to be `origin`.
|
|
75
|
+
*/
|
|
76
|
+
export function ledgerOnBranchArgv(remote: string, branch: string, rel: string): string[] {
|
|
77
|
+
return ['cat-file', '-e', `${remote}/${branch}:${rel}`];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Why the release refuses to continue without a ledger on the branch.
|
|
82
|
+
*
|
|
83
|
+
* Continuing would merge and tag with no ledger, and an absent ledger becomes a
|
|
84
|
+
* repo-wide failure the moment the tag exists — that is the six-release failure
|
|
85
|
+
* this mechanism ends, so it is a stop rather than a warning.
|
|
86
|
+
*
|
|
87
|
+
* The causes are named because the operator has to pick one and most of them
|
|
88
|
+
* are ordinary. With the ingest in CI, "it has not happened yet" is the common
|
|
89
|
+
* case and waiting is the answer; a repository without the review secret never
|
|
90
|
+
* gets one at all and needs the ledger by hand, once per release, which is a
|
|
91
|
+
* real cost and is stated here rather than discovered.
|
|
92
|
+
*/
|
|
93
|
+
export function ledgerAbsentMessage(version: string, branch: string, remote: string): string {
|
|
94
|
+
return (
|
|
95
|
+
`${ledgerRelPath(version)} is not on ${remote}/${branch}.\n` +
|
|
96
|
+
' The release stops: continuing would merge and tag with no findings ledger, and an ' +
|
|
97
|
+
'absent ledger for a shipped version reds every pull request in the repository.\n' +
|
|
98
|
+
` The ${FINDINGS_WORKFLOW} workflow commits it to the release branch once it has ` +
|
|
99
|
+
'reviewed the head. Ordinary causes, in the order to check them: the review has not ' +
|
|
100
|
+
'finished yet (wait, then resume); the review found nothing and its commit is still in ' +
|
|
101
|
+
'flight (same); no ANTHROPIC_API_KEY, so no review ran and no ledger will appear — write ' +
|
|
102
|
+
`one with a no_findings_reason and push it to ${branch}; no RELEASE_PR_TOKEN, in which ` +
|
|
103
|
+
'case the job refuses to push rather than deadlock this wait and says so as a warning in ' +
|
|
104
|
+
'its run log — configure the PAT, or write the ledger by hand; or the workflow could not ' +
|
|
105
|
+
'push, which its run log will say.\n' +
|
|
106
|
+
' Then: `git pull` on the release branch, and resume.'
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Why the release refuses to continue when the PR is already merged and the
|
|
112
|
+
* ledger is not on the trunk either.
|
|
113
|
+
*
|
|
114
|
+
* This is the state the whole mechanism exists to prevent, reached the one way
|
|
115
|
+
* that survives every guard before it: the ingest produced nothing, step 7
|
|
116
|
+
* stopped, and the PR was merged by hand anyway. A resumed run then finds
|
|
117
|
+
* `state === 'MERGED'` and — until this check existed — printed "the ledger
|
|
118
|
+
* rode in with it" without reading anything, tagged, and published. The absent
|
|
119
|
+
* ledger for a shipped version is what reds every pull request in the
|
|
120
|
+
* repository, so the assertion had to become a question.
|
|
121
|
+
*
|
|
122
|
+
* The release branch is gone by now, so there is no workflow run left to wait
|
|
123
|
+
* for: the remaining path is a ledger written onto the trunk by hand.
|
|
124
|
+
*/
|
|
125
|
+
export function ledgerAbsentAfterMergeMessage(
|
|
126
|
+
version: string,
|
|
127
|
+
trunk: string,
|
|
128
|
+
remote: string,
|
|
129
|
+
): string {
|
|
130
|
+
return (
|
|
131
|
+
`${ledgerRelPath(version)} is on neither the release branch nor ${remote}/${trunk}, and ` +
|
|
132
|
+
'the release pull request is already merged.\n' +
|
|
133
|
+
' The release stops: tagging now ships a version whose findings ledger does not exist, ' +
|
|
134
|
+
'and an absent ledger for a shipped version reds every pull request in the repository.\n' +
|
|
135
|
+
` The release branch is gone, so the ${FINDINGS_WORKFLOW} run that would have committed ` +
|
|
136
|
+
'the ledger cannot be waited for. Write the ledger on the trunk instead — the review for ' +
|
|
137
|
+
'this version is in its own workflow run, or record a no_findings_reason if none ran — ' +
|
|
138
|
+
'push it, and resume.'
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* The message a release stops with when the disposition gate refuses.
|
|
144
|
+
*
|
|
145
|
+
* `blocking` is what the release could count itself: findings that are blocking
|
|
146
|
+
* and carry no `status`. It is deliberately NOT presented as the reason — the
|
|
147
|
+
* gate refuses for more shapes than that (an unknown status, an empty rationale
|
|
148
|
+
* or verifier, a `fixed` with no commit, a malformed ledger, an undeterminable
|
|
149
|
+
* release status), and an earlier version of this message asserted "N blocking
|
|
150
|
+
* … carry no disposition" for every one of them. At N = 0 that produced an
|
|
151
|
+
* instruction nobody could follow.
|
|
152
|
+
*
|
|
153
|
+
* So the gate's own output is the reason, passed in and printed, and this text
|
|
154
|
+
* only says where the file is, why the release stopped, and how to resume.
|
|
155
|
+
*/
|
|
156
|
+
export function dispositionStopMessage(
|
|
157
|
+
version: string,
|
|
158
|
+
gateOutput: string,
|
|
159
|
+
blocking: number,
|
|
160
|
+
resumeCmd: string,
|
|
161
|
+
): string {
|
|
162
|
+
const count =
|
|
163
|
+
blocking > 0 ? ` ${blocking} of them are blocking findings with no status yet.\n` : '';
|
|
164
|
+
return (
|
|
165
|
+
`the disposition gate refuses ${version}. Its own report:\n` +
|
|
166
|
+
`${gateOutput.trim() || ' (the gate printed nothing — run it directly to see why)'}\n` +
|
|
167
|
+
count +
|
|
168
|
+
` The ledger is at ${ledgerRelPath(version)} and the release stops here by design: a ` +
|
|
169
|
+
'disposition is an adjudication of what this release ships, with a rationale and a ' +
|
|
170
|
+
'named verifier, and no automation may write one.\n' +
|
|
171
|
+
` Resolve what the report names, push the release branch, then: ${resumeCmd}`
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** The release's own subprocess result shape, mirrored so this module stays free of it. */
|
|
176
|
+
interface StepRunResult {
|
|
177
|
+
returncode: number;
|
|
178
|
+
stdout: string;
|
|
179
|
+
stderr: string;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* What the step needs from the release script, injected rather than imported.
|
|
184
|
+
*
|
|
185
|
+
* `release.ts` sits past the source-size cap where every line is charged, and
|
|
186
|
+
* this step is the release's side of the contract this module already owns — so
|
|
187
|
+
* it lives here. Injection rather than an import of `release_publication.ts`
|
|
188
|
+
* keeps `_lib` free of a dependency on its own caller.
|
|
189
|
+
*/
|
|
190
|
+
export interface LedgerStepDeps {
|
|
191
|
+
run: (argv: string[], opts: { check: boolean; capture: boolean }) => StepRunResult;
|
|
192
|
+
die: (msg: string) => never;
|
|
193
|
+
/** Prints the step banner, so the caller keeps the step number. */
|
|
194
|
+
step: (msg: string) => void;
|
|
195
|
+
/** Where the step reports the ref it read. */
|
|
196
|
+
write: (s: string) => void;
|
|
197
|
+
/** Absolute repository root, for resolving the ledger on disk. */
|
|
198
|
+
repoRoot: string;
|
|
199
|
+
/** Remote name, never assumed to be `origin`. */
|
|
200
|
+
remote: string;
|
|
201
|
+
/** The trunk the release merges into — the ref to ask once the branch is gone. */
|
|
202
|
+
trunk: string;
|
|
203
|
+
/**
|
|
204
|
+
* The PR number for `--pr`, resolved late.
|
|
205
|
+
*
|
|
206
|
+
* Late because the release probes its PR once at the top and only on a
|
|
207
|
+
* resumed run, so on a first run the number was null here and `--pr` was
|
|
208
|
+
* silently dropped — and the release then passed a strictly weaker check
|
|
209
|
+
* than `finding-dispositions`, learning about an un-ingested finding from
|
|
210
|
+
* CI instead. By the time this step runs the PR exists either way.
|
|
211
|
+
*/
|
|
212
|
+
resolvePr: () => number | null;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Verify the release carries its own findings ledger, or stop.
|
|
217
|
+
*
|
|
218
|
+
* VERIFIES, NEVER PRODUCES — the why is the module docstring above. Placed
|
|
219
|
+
* between the check wait and the merge: the ledger lives on the release branch
|
|
220
|
+
* and the merge deletes it, so this is the last moment the question means
|
|
221
|
+
* anything, and after the wait so a red `finding-dispositions` has already
|
|
222
|
+
* stopped the release with the check's own name rather than a duplicate of it.
|
|
223
|
+
*
|
|
224
|
+
* Two questions, each answered with a stop:
|
|
225
|
+
*
|
|
226
|
+
* 1. Is the ledger on the ref the merge will read? On an open PR that is the
|
|
227
|
+
* remote release branch; once the PR is merged the branch is deleted and
|
|
228
|
+
* the ledger, if it was ever produced, rode into the trunk. The merged
|
|
229
|
+
* path used to ask nothing and assert the good case.
|
|
230
|
+
* 2. Does the disposition gate pass, in `--pr` mode — the same mode CI uses,
|
|
231
|
+
* so the release cannot pass a weaker check than the one it is trying to
|
|
232
|
+
* pre-satisfy.
|
|
233
|
+
*
|
|
234
|
+
* Neither answer is repaired here. Filling a disposition states what the release
|
|
235
|
+
* ships, with a rationale and a named verifier; no automation writes one.
|
|
236
|
+
*/
|
|
237
|
+
export function settleFindingsLedger(
|
|
238
|
+
deps: LedgerStepDeps,
|
|
239
|
+
version: string,
|
|
240
|
+
branch: string,
|
|
241
|
+
merged: boolean,
|
|
242
|
+
): void {
|
|
243
|
+
deps.step(
|
|
244
|
+
merged
|
|
245
|
+
? 'Verify the findings ledger rode in with the merge'
|
|
246
|
+
: 'Verify the self-review findings ledger',
|
|
247
|
+
);
|
|
248
|
+
const rel = ledgerRelPath(version);
|
|
249
|
+
const ref = merged ? deps.trunk : branch;
|
|
250
|
+
|
|
251
|
+
// REFRESH BEFORE READING, AND FAST-FORWARD BEFORE ASKING THE GATE. Both
|
|
252
|
+
// halves are a defect a fourth review measured, and they are the same
|
|
253
|
+
// defect seen from two sides. `cat-file -e <remote>/<ref>:<path>` reads
|
|
254
|
+
// `.git`, not GitHub — and nothing in a first run refreshes that
|
|
255
|
+
// remote-tracking ref after CI commits the ledger: preflight fetches before
|
|
256
|
+
// the branch exists, and step 4's push sets the ref to the pushed commit,
|
|
257
|
+
// which is strictly older than the ledger commit. So the probe answered
|
|
258
|
+
// "absent" on every first release. The disposition gate then reads the
|
|
259
|
+
// WORKING TREE, which the same push left equally stale, so a fetch alone
|
|
260
|
+
// would fix the probe and hand the gate an empty ledger instead.
|
|
261
|
+
//
|
|
262
|
+
// `--ff-only` on purpose: the release pushed this ref itself, so the only
|
|
263
|
+
// commit ahead of it should be CI's. Anything else means the branch moved
|
|
264
|
+
// under the run, and stopping is better than merging a tree nobody read.
|
|
265
|
+
// Both are `check: false` — a fetch that fails leaves the probe to report
|
|
266
|
+
// the absence with a message that says what to do.
|
|
267
|
+
deps.run(['git', 'fetch', deps.remote, ref], { check: false, capture: true });
|
|
268
|
+
deps.run(['git', 'pull', '--ff-only', deps.remote, ref], { check: false, capture: true });
|
|
269
|
+
|
|
270
|
+
const onBranch =
|
|
271
|
+
deps.run(['git', ...ledgerOnBranchArgv(deps.remote, ref, rel)], {
|
|
272
|
+
check: false,
|
|
273
|
+
capture: true,
|
|
274
|
+
}).returncode === 0;
|
|
275
|
+
if (!onBranch) {
|
|
276
|
+
deps.die(
|
|
277
|
+
merged
|
|
278
|
+
? ledgerAbsentAfterMergeMessage(version, deps.trunk, deps.remote)
|
|
279
|
+
: ledgerAbsentMessage(version, branch, deps.remote),
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
deps.write(` ledger on ${deps.remote}/${ref}: ${rel}\n`);
|
|
283
|
+
|
|
284
|
+
const argv = ['./scripts-run', 'src/scripts/check_finding_dispositions', '--release', version];
|
|
285
|
+
const pr = deps.resolvePr();
|
|
286
|
+
if (pr !== null) {
|
|
287
|
+
argv.push('--pr', String(pr));
|
|
288
|
+
}
|
|
289
|
+
const verdict = deps.run(argv, { check: false, capture: true });
|
|
290
|
+
if (verdict.returncode !== 0) {
|
|
291
|
+
deps.die(
|
|
292
|
+
dispositionStopMessage(
|
|
293
|
+
version,
|
|
294
|
+
// BOTH streams. The gate writes its scan line to stdout and its
|
|
295
|
+
// per-finding diagnosis to stderr, so preferring stdout showed
|
|
296
|
+
// the operator `scanned: N` and discarded the entire reason the
|
|
297
|
+
// release stopped.
|
|
298
|
+
[verdict.stdout, verdict.stderr].map((s) => s.trim()).filter(Boolean).join('\n'),
|
|
299
|
+
blockingWithoutDisposition(path.join(deps.repoRoot, rel)),
|
|
300
|
+
'task release -- --resume --yes',
|
|
301
|
+
),
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* How many blocking findings carry no status — a figure for the stop message,
|
|
308
|
+
* never the reason for it.
|
|
309
|
+
*
|
|
310
|
+
* The gate refuses for more shapes than this counts (an unknown status, an
|
|
311
|
+
* empty rationale or verifier, a `fixed` with no commit, a malformed ledger),
|
|
312
|
+
* which is why the gate's own output is what the operator is shown.
|
|
313
|
+
*/
|
|
314
|
+
function blockingWithoutDisposition(ledgerAbs: string): number {
|
|
315
|
+
if (!fs.existsSync(ledgerAbs)) {
|
|
316
|
+
return 0;
|
|
317
|
+
}
|
|
318
|
+
try {
|
|
319
|
+
const ledger = parse_ledger(fs.readFileSync(ledgerAbs, 'utf-8'), ledgerAbs);
|
|
320
|
+
return ledger.findings.filter((f) => isBlocking(f) && !f.status).length;
|
|
321
|
+
} catch {
|
|
322
|
+
return 0;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `--ci` fallback dispatch of the three tag-triggered workflows.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from `release.ts` as a lowering commit under
|
|
5
|
+
* `check_source_size_budget`, whose own contract names splitting an
|
|
6
|
+
* over-ceiling file as the improvement it exists to force. The block is
|
|
7
|
+
* self-contained — three workflow names, one loop, one warning — and nothing
|
|
8
|
+
* else in step 10 reads it.
|
|
9
|
+
*
|
|
10
|
+
* WHY IT EXISTS. A tag pushed with the default `GITHUB_TOKEN` fires no
|
|
11
|
+
* tag-triggered workflow: GitHub's recursion guard suppresses the event. All
|
|
12
|
+
* three workflows accept a `tag` input for exactly this recovery, so under
|
|
13
|
+
* `--ci` the release dispatches them rather than waiting for an event that will
|
|
14
|
+
* never arrive. When the tag was pushed with a PAT they already fired and this
|
|
15
|
+
* is redundant.
|
|
16
|
+
*
|
|
17
|
+
* WHY IT NEVER FAILS THE RELEASE. By the time it runs the release is complete —
|
|
18
|
+
* the tag is pushed, the GitHub Release is created, npm publishes
|
|
19
|
+
* asynchronously. Dispatching through the API additionally needs the token's
|
|
20
|
+
* `actions:write` scope, and a 403 for a missing scope must not mark an
|
|
21
|
+
* already-shipped release as failed. So it warns and continues.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/** The tag-triggered workflows, in the order the release dispatches them. */
|
|
25
|
+
export const TAG_TRIGGERED_WORKFLOWS = [
|
|
26
|
+
'release-guard.yml',
|
|
27
|
+
'publish-npm.yml',
|
|
28
|
+
'cloud-release.yml',
|
|
29
|
+
] as const;
|
|
30
|
+
|
|
31
|
+
interface DispatchRunResult {
|
|
32
|
+
returncode: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface TagDispatchDeps {
|
|
36
|
+
run: (argv: string[], opts: { check: boolean }) => DispatchRunResult;
|
|
37
|
+
/** Where a non-fatal dispatch failure is reported. */
|
|
38
|
+
warn: (s: string) => void;
|
|
39
|
+
/** The ref the dispatch runs against — the trunk. */
|
|
40
|
+
trunk: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Why one failed dispatch is a warning and not a stop, said to the operator. */
|
|
44
|
+
export function dispatchWarning(workflow: string, code: number, version: string): string {
|
|
45
|
+
return (
|
|
46
|
+
`⚠️ Could not dispatch ${workflow} (exit ${code}) — the release ${version} is ` +
|
|
47
|
+
`already complete (tag + GitHub Release created; npm publishes async). If the tag was ` +
|
|
48
|
+
`pushed with a PAT, ${workflow} already fired on the tag push. If you rely on the explicit ` +
|
|
49
|
+
`dispatch, grant RELEASE_PR_TOKEN the "Actions: read and write" scope (fine-grained PAT) ` +
|
|
50
|
+
`or the "workflow" scope (classic PAT).\n`
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function dispatchTagWorkflows(deps: TagDispatchDeps, version: string): void {
|
|
55
|
+
for (const wf of TAG_TRIGGERED_WORKFLOWS) {
|
|
56
|
+
const r = deps.run(['gh', 'workflow', 'run', wf, '--ref', deps.trunk, '-f', `tag=${version}`], {
|
|
57
|
+
check: false,
|
|
58
|
+
});
|
|
59
|
+
if (r.returncode !== 0) {
|
|
60
|
+
deps.warn(dispatchWarning(wf, r.returncode, version));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|