@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,424 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The standing-payload ceiling, MEASURED at the base ref rather than stored.
|
|
3
|
+
*
|
|
4
|
+
* ceiling = max(design_ceiling, effective_base + active grant)
|
|
5
|
+
*
|
|
6
|
+
* WHY MEASURED
|
|
7
|
+
* ------------
|
|
8
|
+
* An AI council (2/2 convergent, 2026-09-10, under a written owner delegation)
|
|
9
|
+
* fixed the formula, and the reason for the move is one sentence from that
|
|
10
|
+
* verdict: a measured ceiling **captures every merged reduction
|
|
11
|
+
* automatically**, where a stored one stays at its last hand-written number —
|
|
12
|
+
* so payload a merge removed can be added straight back into the space it
|
|
13
|
+
* freed. That is the defect `ci_delivery.grace_ceiling` had for its whole life.
|
|
14
|
+
*
|
|
15
|
+
* WHY NO PER-PR HEADROOM. Both seats, without qualification: *"Neither a
|
|
16
|
+
* percentage nor a fixed token allowance is safe against a moving base: both
|
|
17
|
+
* authorize cumulative growth."* One seat put the arithmetic on it —
|
|
18
|
+
* 138,413 × 1.05^10 ≈ 225,000 after ten pull requests. `headroom_pct` derives
|
|
19
|
+
* the FIXED design ceiling from `baseline_tokens` and is never re-applied to a
|
|
20
|
+
* moving base. So the ordinary path is ZERO NET GROWTH while the tree is over
|
|
21
|
+
* design, and the design ceiling once it is at or below. 96.8 % of the last
|
|
22
|
+
* 250 merged pull requests already move this payload by zero or less.
|
|
23
|
+
*
|
|
24
|
+
* THE STORED TERM IS GONE — STAGE 2 LANDED 2026-09-11
|
|
25
|
+
* ----------------------------------------------------
|
|
26
|
+
* A second council round (2/2, 2026-09-11) refused to let the stored ceiling be
|
|
27
|
+
* removed in the change that INTRODUCED the measured one, on a structural
|
|
28
|
+
* ground rather than a cautious one. Under prerequisite 3 the gate runs AS IT
|
|
29
|
+
* EXISTS AT THE BASE REF, so — openai, verbatim — *"the new gate cannot safely
|
|
30
|
+
* validate its own introduction: while the implementation PR runs, the
|
|
31
|
+
* authoritative measuring code at the base ref is still the old
|
|
32
|
+
* implementation."*
|
|
33
|
+
*
|
|
34
|
+
* Stage 1 therefore landed the whole mechanism with the stored ceiling retained
|
|
35
|
+
* as an additional `max` term that could only widen the bound. Stage 2 removes
|
|
36
|
+
* it from a base that already carries this code — verified before the removal
|
|
37
|
+
* by running the base-ref copy of the gate against the head tree, which is the
|
|
38
|
+
* precondition the sequencing was about. `ci_delivery` now stores no ceiling at
|
|
39
|
+
* all, so the bound cannot be widened by editing a field. ADR-275 records the
|
|
40
|
+
* formula and its prerequisites; ADR-276 records this removal and the required
|
|
41
|
+
* status check that made it meaningful.
|
|
42
|
+
*
|
|
43
|
+
* THE EXCEPTION PATH, AND WHY THE WATERMARK IS THE LOAD-BEARING FIELD
|
|
44
|
+
* -------------------------------------------------------------------
|
|
45
|
+
* A change whose offsetting reduction is genuinely unsafe takes a recorded,
|
|
46
|
+
* approved, dated grant. Both seats specified the same six properties, and one
|
|
47
|
+
* is easy to lose: *"the exceptional measurement must NEVER become the next
|
|
48
|
+
* base."* Under a base-measured ceiling that is a mechanism, not a note —
|
|
49
|
+
* without it a grant of N tokens raises the measurement, the next pull request
|
|
50
|
+
* measures the raised base, and the grant is permanent one merge later.
|
|
51
|
+
* `effectiveBase` pins the base to the WATERMARK recorded at grant time for as
|
|
52
|
+
* long as the grant is live.
|
|
53
|
+
*
|
|
54
|
+
* SIX CONTRACT RULES, EACH FROM A BLOCKING FINDING OF THE 2026-09-11 ROUND
|
|
55
|
+
* ------------------------------------------------------------------------
|
|
56
|
+
* 1. AT MOST ONE ACTIVE GRANT. openai: overlapping grants are undefined, and
|
|
57
|
+
* *"'use the highest watermark' is not safe: a later watermark may already
|
|
58
|
+
* contain earlier exceptional growth, causing that growth to be counted both
|
|
59
|
+
* in the anchor and in summed grants."* anthropic preferred defined overlap
|
|
60
|
+
* rules to a ban but called defined semantics blocking either way, so the
|
|
61
|
+
* ban satisfies both seats and the permissive variant does not.
|
|
62
|
+
* 2. APPROVAL MUST BE AUTHENTICATED, NOT ASSERTED. Both seats' hardest
|
|
63
|
+
* pushback: `approved_by` in the pull request that requests the grant is
|
|
64
|
+
* self-asserted data authenticating nothing. A grant therefore carries an
|
|
65
|
+
* `approval_event` — a reference to a platform event outside the diff — and
|
|
66
|
+
* a grant whose approval is unverified is REFUSED rather than honoured.
|
|
67
|
+
* Verification is the CI step's job (it needs the platform); this module
|
|
68
|
+
* refuses anything it was not told is verified.
|
|
69
|
+
* 3. DELETION CANNOT DISCHARGE DEBT. A removed record is not a repaid one.
|
|
70
|
+
* Deletion is caught by the base-ref ratchet, which sees a grant that
|
|
71
|
+
* existed at the base and does not exist at head.
|
|
72
|
+
* 4. `repaid_at` IS A RECORD OF A MEASUREMENT, NOT A CLAIM. Repayment is
|
|
73
|
+
* established by the payload returning to the watermark. A record claiming
|
|
74
|
+
* repayment while the measurement says otherwise is refused.
|
|
75
|
+
* 5. CONSUMPTION IS DERIVED. There is no `consumed_tokens` field to edit:
|
|
76
|
+
* consumption is `measured − watermark`, computed here.
|
|
77
|
+
* 6. EXPIRY IS EVALUATED AT GATE TIME, which is merge time on a required
|
|
78
|
+
* check. A grant that expires while its pull request sits in review reds
|
|
79
|
+
* that pull request; the fix is a fresh approved grant, never an edit to the
|
|
80
|
+
* old one's date, which rule 3's ratchet refuses anyway.
|
|
81
|
+
*
|
|
82
|
+
* WHAT THIS IS NOT, STATED RATHER THAN IMPLIED
|
|
83
|
+
* ---------------------------------------------
|
|
84
|
+
* The ledger is editable by the pull request it governs, like the gate code.
|
|
85
|
+
* The council accepted that for the gate under prerequisite 3 in these terms:
|
|
86
|
+
* *"the mechanism does not prevent the exploit; it makes the exploit auditable
|
|
87
|
+
* … a forensic control, not a preventive one."* Rules 2 and 3 above are what
|
|
88
|
+
* keep the ledger from being weaker than that — an unverified grant buys
|
|
89
|
+
* nothing, and a deleted one is still owed.
|
|
90
|
+
*
|
|
91
|
+
* NO NUMERIC CAP IS ENFORCED, AND THAT IS A FINDING RATHER THAN AN OMISSION.
|
|
92
|
+
* Both seats refused to derive one from the 250-PR delta distribution
|
|
93
|
+
* (p50 0, p90 0, p95 0/+167, max +288): the sample is CENSORED by the very
|
|
94
|
+
* ratchet a cap would relax, so every percentile describes what got through
|
|
95
|
+
* rather than what was attempted. A p95 cap would license the top 5 % of
|
|
96
|
+
* ordinary work to use the break-glass routinely, which makes it not
|
|
97
|
+
* exceptional. The 2026-09-11 round added that the cap must eventually come
|
|
98
|
+
* from actual CONSUMED rather than granted tokens, which rule 5 makes
|
|
99
|
+
* measurable. Until then the approver is the cap.
|
|
100
|
+
*/
|
|
101
|
+
import * as fs from 'node:fs';
|
|
102
|
+
|
|
103
|
+
/** Repo-relative path of the break-glass ledger. */
|
|
104
|
+
export const EXCEPTIONS_CONFIG_PATH = 'src/config/preamble-payload-exceptions.json';
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* A grant's state at evaluation time. Derived, never stored — a stored status
|
|
108
|
+
* would be a second source of truth that drifts against `expires_at`.
|
|
109
|
+
*/
|
|
110
|
+
export type ExceptionState = 'active' | 'repaid' | 'expired';
|
|
111
|
+
|
|
112
|
+
export interface PayloadException {
|
|
113
|
+
id: string;
|
|
114
|
+
granted_tokens: number;
|
|
115
|
+
/** The measured payload immediately BEFORE the grant. The base is pinned here. */
|
|
116
|
+
watermark: number;
|
|
117
|
+
reason: string;
|
|
118
|
+
/**
|
|
119
|
+
* A reference to a platform event that authorised this grant, OUTSIDE the
|
|
120
|
+
* diff requesting it — the council's blocking finding #2. Shape is the CI
|
|
121
|
+
* step's business; this module only requires that one is named and that
|
|
122
|
+
* the caller has verified it.
|
|
123
|
+
*/
|
|
124
|
+
approval_event: string;
|
|
125
|
+
/** ISO date. */
|
|
126
|
+
approved_at: string;
|
|
127
|
+
/** ISO date. After it, an unrepaid grant is a hard refusal. */
|
|
128
|
+
expires_at: string;
|
|
129
|
+
/** ISO date once the payload has measurably returned to the watermark. */
|
|
130
|
+
repaid_at: string | null;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface ExceptionsFile {
|
|
134
|
+
exceptions: PayloadException[];
|
|
135
|
+
/** Schema / parse problems. Non-empty means the file may not be trusted. */
|
|
136
|
+
errors: string[];
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function isIsoDate(v: unknown): v is string {
|
|
140
|
+
return typeof v === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(v);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Read and VALIDATE the ledger. A malformed entry is an error, never a skip.
|
|
145
|
+
*
|
|
146
|
+
* An unreadable or invalid ledger must not silently evaluate as "no
|
|
147
|
+
* exceptions": that reading is permissive in one direction — a corrupted entry
|
|
148
|
+
* stops pinning the base to its watermark — and the caller cannot tell it from
|
|
149
|
+
* an honestly empty file. Callers refuse on `errors`.
|
|
150
|
+
*/
|
|
151
|
+
export function readExceptions(file: string): ExceptionsFile {
|
|
152
|
+
let raw: unknown;
|
|
153
|
+
try {
|
|
154
|
+
raw = JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
155
|
+
} catch (err) {
|
|
156
|
+
const e = err as NodeJS.ErrnoException;
|
|
157
|
+
if (e.code === 'ENOENT') return { exceptions: [], errors: [] };
|
|
158
|
+
return { exceptions: [], errors: [`${file} is not readable as JSON: ${(err as Error).message}`] };
|
|
159
|
+
}
|
|
160
|
+
const root = (raw ?? {}) as Record<string, unknown>;
|
|
161
|
+
const list = root['exceptions'];
|
|
162
|
+
if (list === undefined) return { exceptions: [], errors: [] };
|
|
163
|
+
if (!Array.isArray(list)) return { exceptions: [], errors: [`${file}: 'exceptions' must be an array`] };
|
|
164
|
+
|
|
165
|
+
const errors: string[] = [];
|
|
166
|
+
const out: PayloadException[] = [];
|
|
167
|
+
const ids = new Set<string>();
|
|
168
|
+
list.forEach((item, i) => {
|
|
169
|
+
const e = (item ?? {}) as Record<string, unknown>;
|
|
170
|
+
const where = `${file}: exceptions[${String(i)}]`;
|
|
171
|
+
const id = e['id'];
|
|
172
|
+
const granted = Number(e['granted_tokens']);
|
|
173
|
+
const watermark = Number(e['watermark']);
|
|
174
|
+
const repaid = e['repaid_at'] ?? null;
|
|
175
|
+
if (typeof id !== 'string' || id.trim() === '') errors.push(`${where}: 'id' must be a non-empty string`);
|
|
176
|
+
else if (ids.has(id)) errors.push(`${where}: duplicate id '${id}' — an id is the record's identity`);
|
|
177
|
+
else ids.add(id);
|
|
178
|
+
if (!Number.isInteger(granted) || granted <= 0) {
|
|
179
|
+
errors.push(`${where}: 'granted_tokens' must be a positive integer`);
|
|
180
|
+
}
|
|
181
|
+
if (!Number.isInteger(watermark) || watermark < 0) {
|
|
182
|
+
errors.push(`${where}: 'watermark' must be a non-negative integer — the payload measured at grant time`);
|
|
183
|
+
}
|
|
184
|
+
for (const k of ['reason', 'approval_event'] as const) {
|
|
185
|
+
if (typeof e[k] !== 'string' || (e[k] as string).trim() === '') {
|
|
186
|
+
errors.push(
|
|
187
|
+
`${where}: '${k}' must be a non-empty string` +
|
|
188
|
+
(k === 'approval_event'
|
|
189
|
+
? ". An approval recorded only by the diff requesting it authenticates nothing — name the platform event that authorised it."
|
|
190
|
+
: ''),
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
for (const k of ['approved_at', 'expires_at'] as const) {
|
|
195
|
+
if (!isIsoDate(e[k])) errors.push(`${where}: '${k}' must be a YYYY-MM-DD date`);
|
|
196
|
+
}
|
|
197
|
+
if (repaid !== null && !isIsoDate(repaid)) {
|
|
198
|
+
errors.push(`${where}: 'repaid_at' must be a YYYY-MM-DD date or null`);
|
|
199
|
+
}
|
|
200
|
+
if (e['consumed_tokens'] !== undefined) {
|
|
201
|
+
errors.push(
|
|
202
|
+
`${where}: 'consumed_tokens' is not a field. Consumption is DERIVED as measured − watermark; ` +
|
|
203
|
+
'a stored copy would be an editable assertion about a measurement, which is the shape ' +
|
|
204
|
+
'this ledger exists to avoid.',
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
out.push({
|
|
208
|
+
id: typeof id === 'string' ? id : `<entry ${String(i)}>`,
|
|
209
|
+
granted_tokens: Number.isFinite(granted) ? granted : 0,
|
|
210
|
+
watermark: Number.isFinite(watermark) ? watermark : 0,
|
|
211
|
+
reason: String(e['reason'] ?? ''),
|
|
212
|
+
approval_event: String(e['approval_event'] ?? ''),
|
|
213
|
+
approved_at: String(e['approved_at'] ?? ''),
|
|
214
|
+
expires_at: String(e['expires_at'] ?? ''),
|
|
215
|
+
repaid_at: repaid === null ? null : String(repaid),
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
return { exceptions: out, errors };
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/** `today` as `YYYY-MM-DD`, injectable so the expiry branch is testable. */
|
|
222
|
+
export function stateOf(e: PayloadException, today: string): ExceptionState {
|
|
223
|
+
if (e.repaid_at !== null) return 'repaid';
|
|
224
|
+
return e.expires_at < today ? 'expired' : 'active';
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export interface CeilingReading {
|
|
228
|
+
/** The number the payload is compared against. */
|
|
229
|
+
ceiling: number;
|
|
230
|
+
/** `round(baseline_tokens * (1 + headroom_pct/100))`. The floor of the ceiling. */
|
|
231
|
+
designCeiling: number;
|
|
232
|
+
/** Payload measured at the base ref, or `null` when it could not be read. */
|
|
233
|
+
basePayload: number | null;
|
|
234
|
+
/** The base after watermark pinning, or `null` with `basePayload`. */
|
|
235
|
+
effectiveBase: number | null;
|
|
236
|
+
/** `granted_tokens` of the single active grant, else 0. */
|
|
237
|
+
activeGrants: number;
|
|
238
|
+
activeIds: string[];
|
|
239
|
+
/** Which term set the ceiling — the one thing a reader needs at a glance. */
|
|
240
|
+
boundBy: 'design' | 'base' | 'grant';
|
|
241
|
+
/** True when the ceiling rests on a base reading that was actually taken. */
|
|
242
|
+
verified: boolean;
|
|
243
|
+
ok: boolean;
|
|
244
|
+
violations: string[];
|
|
245
|
+
/** Printed on the passing path too, so a skip cannot pass for a check. */
|
|
246
|
+
note: string | null;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export interface CeilingOptions {
|
|
250
|
+
designCeiling: number;
|
|
251
|
+
/** `null` = the base ref could not be measured. */
|
|
252
|
+
basePayload: number | null;
|
|
253
|
+
/** Why it could not be measured. Rendered verbatim. */
|
|
254
|
+
baseNote?: string | null;
|
|
255
|
+
/** The payload measured in THIS tree — needed to corroborate `repaid_at`. */
|
|
256
|
+
headPayload: number;
|
|
257
|
+
exceptions?: readonly PayloadException[];
|
|
258
|
+
exceptionErrors?: readonly string[];
|
|
259
|
+
/**
|
|
260
|
+
* Ids whose `approval_event` the caller VERIFIED against the platform.
|
|
261
|
+
*
|
|
262
|
+
* Absent means nothing was verified, which is the safe default: a grant is
|
|
263
|
+
* honoured only when someone with access to the platform said so.
|
|
264
|
+
*/
|
|
265
|
+
verifiedApprovals?: readonly string[];
|
|
266
|
+
/** `YYYY-MM-DD`. Injected so the expiry branch is testable. */
|
|
267
|
+
today: string;
|
|
268
|
+
/**
|
|
269
|
+
* Refuse instead of falling back when the base could not be measured.
|
|
270
|
+
*
|
|
271
|
+
* Advisory is the default and keeps a shallow clone, a first commit and a
|
|
272
|
+
* detached build usable — the same argument `standing_bound_ratchet` makes
|
|
273
|
+
* for its own mode gate, and the same reason the flag is the caller's
|
|
274
|
+
* rather than sniffed from an environment variable here.
|
|
275
|
+
*/
|
|
276
|
+
requireBase?: boolean;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Compute the effective ceiling and say whether it may be trusted.
|
|
281
|
+
*
|
|
282
|
+
* Pure: it takes a base reading rather than producing one, so every branch —
|
|
283
|
+
* expiry, watermark pinning, unverified approval, fail-closed base — is
|
|
284
|
+
* testable without git or a platform.
|
|
285
|
+
*/
|
|
286
|
+
export function computeCeiling(opts: CeilingOptions): CeilingReading {
|
|
287
|
+
const exceptions = opts.exceptions ?? [];
|
|
288
|
+
const verified = new Set(opts.verifiedApprovals ?? []);
|
|
289
|
+
const violations = [...(opts.exceptionErrors ?? [])];
|
|
290
|
+
|
|
291
|
+
const live = exceptions.filter((e) => stateOf(e, opts.today) !== 'repaid');
|
|
292
|
+
const expired = live.filter((e) => stateOf(e, opts.today) === 'expired');
|
|
293
|
+
const candidates = live.filter((e) => stateOf(e, opts.today) === 'active');
|
|
294
|
+
|
|
295
|
+
// Rule 1 — at most one active grant. Summing overlapping grants can count
|
|
296
|
+
// exceptional growth twice: in a later watermark that already contains it,
|
|
297
|
+
// and again in the sum.
|
|
298
|
+
if (candidates.length > 1) {
|
|
299
|
+
violations.push(
|
|
300
|
+
`${String(candidates.length)} standing-payload exceptions are active at once ` +
|
|
301
|
+
`(${candidates.map((e) => e.id).join(', ')}). At most one may be. Overlapping grants have no ` +
|
|
302
|
+
'defined composition: a later watermark can already contain an earlier grant\'s growth, so ' +
|
|
303
|
+
'summing counts it twice. Repay or expire one before recording the next.',
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Rule 2 — an unverified approval buys nothing.
|
|
308
|
+
for (const e of candidates) {
|
|
309
|
+
if (!verified.has(e.id)) {
|
|
310
|
+
violations.push(
|
|
311
|
+
`standing-payload exception '${e.id}' has no VERIFIED approval. It names ` +
|
|
312
|
+
`'${e.approval_event}', and nothing in this run confirmed that event. An approval recorded ` +
|
|
313
|
+
'only by the change that requests it is self-asserted data: the same diff can claim the ' +
|
|
314
|
+
'grant, the approver and the date. The grant is refused until the platform event is ' +
|
|
315
|
+
'checked. This is not a payload problem — do not shrink the change to clear it.',
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Rule 6 — expiry is evaluated now, which on a required check is merge time.
|
|
321
|
+
for (const e of expired) {
|
|
322
|
+
violations.push(
|
|
323
|
+
`standing-payload exception '${e.id}' expired on ${e.expires_at} and is not repaid. ` +
|
|
324
|
+
`It granted ${String(e.granted_tokens)} tok over a watermark of ${String(e.watermark)}. ` +
|
|
325
|
+
'Bring the payload back to the watermark and record repaid_at, or obtain a fresh approved ' +
|
|
326
|
+
"grant — editing this one's expiry is refused by the shrink-only ratchet, and an expiry " +
|
|
327
|
+
'that lapsed quietly would renew the grant by inaction.',
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Rule 4 — `repaid_at` records a measurement; it does not assert one.
|
|
332
|
+
for (const e of exceptions) {
|
|
333
|
+
if (e.repaid_at !== null && opts.headPayload > e.watermark) {
|
|
334
|
+
violations.push(
|
|
335
|
+
`standing-payload exception '${e.id}' is marked repaid on ${e.repaid_at}, but the payload ` +
|
|
336
|
+
`measures ${String(opts.headPayload)} against its watermark of ${String(e.watermark)} — ` +
|
|
337
|
+
`${String(opts.headPayload - e.watermark)} tok still outstanding. Repayment is established ` +
|
|
338
|
+
'by the measurement returning to the watermark; the field records that event and cannot ' +
|
|
339
|
+
'substitute for it.',
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const activeGrants = candidates.length === 1 ? (candidates[0]?.granted_tokens ?? 0) : 0;
|
|
345
|
+
const activeIds = candidates.map((e) => e.id);
|
|
346
|
+
|
|
347
|
+
if (opts.basePayload === null) {
|
|
348
|
+
const why = opts.baseNote ?? 'the base ref could not be measured';
|
|
349
|
+
const fallback = opts.designCeiling;
|
|
350
|
+
if (opts.requireBase === true) {
|
|
351
|
+
violations.push(
|
|
352
|
+
`the standing-payload ceiling could not be measured: ${why}. This run is ENFORCING, so an ` +
|
|
353
|
+
'unmeasurable base refuses rather than falling back — a base that cannot be read would ' +
|
|
354
|
+
'otherwise grant an unbounded budget on an infrastructure failure. This is NOT payload ' +
|
|
355
|
+
'growth: fix the checkout (a full fetch of the base ref) rather than shrinking the change.',
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
return {
|
|
359
|
+
ceiling: fallback,
|
|
360
|
+
designCeiling: opts.designCeiling,
|
|
361
|
+
basePayload: null,
|
|
362
|
+
effectiveBase: null,
|
|
363
|
+
activeGrants,
|
|
364
|
+
activeIds,
|
|
365
|
+
boundBy: 'design',
|
|
366
|
+
verified: false,
|
|
367
|
+
ok: violations.length === 0 && opts.requireBase !== true,
|
|
368
|
+
note: `${why}, so the ceiling is NOT a base-measured reading`,
|
|
369
|
+
violations,
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// The watermark pin. Without it a grant raises the measurement, the next
|
|
374
|
+
// pull request measures the raised base, and the grant is permanent.
|
|
375
|
+
const effectiveBase =
|
|
376
|
+
candidates.length === 1
|
|
377
|
+
? Math.min(opts.basePayload, candidates[0]?.watermark ?? opts.basePayload)
|
|
378
|
+
: opts.basePayload;
|
|
379
|
+
|
|
380
|
+
// An unverified or over-subscribed grant contributes ZERO, so a refused
|
|
381
|
+
// grant can never widen the bound it was refused for.
|
|
382
|
+
const honoured = violations.length === 0 ? activeGrants : 0;
|
|
383
|
+
const measuredTerm = effectiveBase + honoured;
|
|
384
|
+
const ceiling = Math.max(opts.designCeiling, measuredTerm);
|
|
385
|
+
|
|
386
|
+
let boundBy: CeilingReading['boundBy'] = 'design';
|
|
387
|
+
if (ceiling === measuredTerm && ceiling > opts.designCeiling) boundBy = honoured > 0 ? 'grant' : 'base';
|
|
388
|
+
|
|
389
|
+
return {
|
|
390
|
+
ceiling,
|
|
391
|
+
designCeiling: opts.designCeiling,
|
|
392
|
+
basePayload: opts.basePayload,
|
|
393
|
+
effectiveBase,
|
|
394
|
+
activeGrants: honoured,
|
|
395
|
+
activeIds,
|
|
396
|
+
boundBy,
|
|
397
|
+
verified: true,
|
|
398
|
+
ok: violations.length === 0,
|
|
399
|
+
violations,
|
|
400
|
+
note: null,
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/** The human rendering, printed on BOTH paths — a check that only speaks when
|
|
405
|
+
* it fails is a check nobody audits until it is already load-bearing. */
|
|
406
|
+
export function renderCeiling(c: CeilingReading): string {
|
|
407
|
+
const lines: string[] = [];
|
|
408
|
+
if (!c.verified) {
|
|
409
|
+
lines.push(` ⚠️ ceiling NOT measured — ${c.note ?? 'no reason recorded'}\n`);
|
|
410
|
+
lines.push(` falling back to ${String(c.ceiling)} tok (design ${String(c.designCeiling)}).\n`);
|
|
411
|
+
} else {
|
|
412
|
+
const pinned = c.effectiveBase !== c.basePayload;
|
|
413
|
+
const how =
|
|
414
|
+
c.boundBy === 'design'
|
|
415
|
+
? `the DESIGN ceiling — the measured base (${String(c.basePayload ?? 0)}) is at or below it`
|
|
416
|
+
: `base ${String(c.effectiveBase ?? 0)}` +
|
|
417
|
+
(pinned ? ` (PINNED to an exception watermark; measured ${String(c.basePayload ?? 0)})` : '') +
|
|
418
|
+
(c.activeGrants > 0 ? ` + ${String(c.activeGrants)} granted` : '') +
|
|
419
|
+
` — zero net growth, design ${String(c.designCeiling)}`;
|
|
420
|
+
lines.push(` ✅ ceiling ${String(c.ceiling)} tok = ${how}.\n`);
|
|
421
|
+
}
|
|
422
|
+
if (c.activeIds.length > 0) lines.push(` active exception(s): ${c.activeIds.join(', ')}\n`);
|
|
423
|
+
return lines.join('');
|
|
424
|
+
}
|
|
@@ -241,9 +241,8 @@ export type Slot =
|
|
|
241
241
|
* Default firing period per slot, before per-platform native-event corrections.
|
|
242
242
|
*
|
|
243
243
|
* `stop` is per-turn, NOT session end. On Claude Code the native `Stop` event
|
|
244
|
-
* fires after every assistant reply
|
|
245
|
-
*
|
|
246
|
-
* i.e. a working-memory refresh per reply. True session end is the separate
|
|
244
|
+
* fires after every assistant reply, so a concern bound there runs once per
|
|
245
|
+
* reply rather than once per session. True session end is the separate
|
|
247
246
|
* `session_end` slot.
|
|
248
247
|
*/
|
|
249
248
|
const SLOT_FREQUENCY_DEFAULT: Record<Slot, Frequency> = {
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Is the payload census still measuring everything payload-shaped?
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS EXISTS — prerequisite 4c of the measured-ceiling verdict
|
|
5
|
+
* -----------------------------------------------------------------
|
|
6
|
+
* An AI council (2/2, 2026-09-10) named a gap neither earlier round had: *"a
|
|
7
|
+
* pull request can move payload into a location the measurement does not
|
|
8
|
+
* enumerate, and no ceiling formula sees that."* Both seats were equally clear
|
|
9
|
+
* that this is NOT a reason to prefer a stored ceiling — the same move defeats
|
|
10
|
+
* a stored number exactly as it defeats a measured one — so it is an
|
|
11
|
+
* independent defect with its own mitigation: *"an exhaustiveness check that
|
|
12
|
+
* fails when a payload-shaped file sits outside every known bucket."*
|
|
13
|
+
*
|
|
14
|
+
* TWO WAYS PAYLOAD ESCAPES THE CENSUS, AND BOTH ARE CHECKED
|
|
15
|
+
* ----------------------------------------------------------
|
|
16
|
+
* 1. A NEW PROJECTED TREE. Something lands under `dist/agent-src/` that a host
|
|
17
|
+
* loads into standing context, and no bucket covers it. Every directory
|
|
18
|
+
* there is therefore either a declared prefix-stable surface or carries an
|
|
19
|
+
* explicit on-demand classification WITH its reason. A tree that is neither
|
|
20
|
+
* reds until a human classifies it. "Unclassified" is the state this check
|
|
21
|
+
* exists to make loud; guessing on its behalf is what produced the gap.
|
|
22
|
+
*
|
|
23
|
+
* 2. A RULE BODY OUTSIDE THE RULES BUCKET. A file with rule frontmatter is
|
|
24
|
+
* standing payload by construction — the router delivers it — so one
|
|
25
|
+
* sitting outside `dist/agent-src/rules` is measured by nothing while
|
|
26
|
+
* behaving exactly like the thing that is measured.
|
|
27
|
+
*
|
|
28
|
+
* WHY THE ON-DEMAND LIST IS HERE AND NOT IN THE BUDGET JSON
|
|
29
|
+
* ----------------------------------------------------------
|
|
30
|
+
* Under prerequisite 3 the gate runs with the code as it exists at the BASE
|
|
31
|
+
* ref, so anything that lives in code pins with it and a pull request cannot
|
|
32
|
+
* widen its own enumeration. A classification kept in the config would be
|
|
33
|
+
* head-side and editable by the change being measured, which is the trust
|
|
34
|
+
* boundary the same verdict spent its sharpest finding on. The measured
|
|
35
|
+
* evidence behind each reason stays in `preamble-payload-budget.json` →
|
|
36
|
+
* `metric.excluded_buckets`, which is where a reader looks for the numbers;
|
|
37
|
+
* this list carries the classification, not the measurement.
|
|
38
|
+
*
|
|
39
|
+
* WHAT IT DOES NOT CLAIM. It sees `dist/agent-src/`. A host that began loading
|
|
40
|
+
* some other tree standing would not appear here at all, and no check in this
|
|
41
|
+
* repository would notice. That reopen condition is the registry's own, stated
|
|
42
|
+
* in `prefix_stable_surfaces.ts`, and this module does not pretend to cover it.
|
|
43
|
+
*/
|
|
44
|
+
import * as fs from 'node:fs';
|
|
45
|
+
import * as path from 'node:path';
|
|
46
|
+
|
|
47
|
+
import { PREFIX_STABLE_SURFACES } from './prefix_stable_surfaces.js';
|
|
48
|
+
|
|
49
|
+
/** The root every projected tree lands under. */
|
|
50
|
+
export const PROJECTION_ROOT = 'dist/agent-src';
|
|
51
|
+
|
|
52
|
+
export interface OnDemandTree {
|
|
53
|
+
/** Directory name directly under `dist/agent-src/`. */
|
|
54
|
+
dir: string;
|
|
55
|
+
/** Why it costs no standing tokens. A classification, not a measurement. */
|
|
56
|
+
why: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Trees that are projected but NOT standing payload.
|
|
61
|
+
*
|
|
62
|
+
* Each reason states the mechanism that keeps it off the preamble, because
|
|
63
|
+
* "it is not standing" with no mechanism behind it is the assumption this
|
|
64
|
+
* whole check exists to stop being made silently.
|
|
65
|
+
*/
|
|
66
|
+
export const ON_DEMAND_TREES: readonly OnDemandTree[] = [
|
|
67
|
+
{ dir: 'commands', why: 'a command body is read when its slash command is invoked, never preloaded' },
|
|
68
|
+
{ dir: 'contexts', why: 'loaded through load_context on demand; no rule declares load_context_eager' },
|
|
69
|
+
{ dir: 'ghostwriter', why: 'persona corpora read by the ghostwriter surface when it runs' },
|
|
70
|
+
{ dir: 'guidelines', why: 'reference material a skill or rule links to; fetched when followed' },
|
|
71
|
+
{ dir: 'packs', why: 'pack manifests read by the installer, not delivered into a session' },
|
|
72
|
+
{ dir: 'personas', why: 'measured at zero standing cost 2026-08-22 — written by generators, read by no host contract' },
|
|
73
|
+
{ dir: 'presets', why: 'installer input, not session content' },
|
|
74
|
+
{ dir: 'profiles', why: 'installer input, not session content' },
|
|
75
|
+
{ dir: 'scripts', why: 'executable support code; never rendered into a prompt' },
|
|
76
|
+
{ dir: 'templates', why: 'scaffolding copied on demand by authoring flows' },
|
|
77
|
+
{ dir: 'user-types', why: 'installer input, not session content' },
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
/** Files under a non-rules tree that legitimately carry rule frontmatter. */
|
|
81
|
+
const RULE_SHAPED_EXEMPT: readonly string[] = [
|
|
82
|
+
// The rule scaffold a new rule is copied FROM. It is frontmatter by
|
|
83
|
+
// definition and is delivered to nobody.
|
|
84
|
+
'dist/agent-src/templates/rule.md',
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
const RULE_TYPE_LINE = /^type:\s*"?(always|auto|manual)"?\s*$/m;
|
|
88
|
+
|
|
89
|
+
function normalise(p: string): string {
|
|
90
|
+
return p.replace(/\\/g, '/').replace(/^\.\//, '').replace(/\/+$/, '');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Directory names directly under the projection root that a surface covers. */
|
|
94
|
+
function declaredTopLevelDirs(): Set<string> {
|
|
95
|
+
const out = new Set<string>();
|
|
96
|
+
const prefix = PROJECTION_ROOT + '/';
|
|
97
|
+
for (const s of PREFIX_STABLE_SURFACES) {
|
|
98
|
+
const root = normalise(s.root);
|
|
99
|
+
if (!root.startsWith(prefix)) continue;
|
|
100
|
+
const rest = root.slice(prefix.length);
|
|
101
|
+
const first = rest.split('/')[0];
|
|
102
|
+
if (first !== undefined && first !== '') out.add(first);
|
|
103
|
+
}
|
|
104
|
+
return out;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function walkMarkdown(dir: string, out: string[]): void {
|
|
108
|
+
let entries: fs.Dirent[];
|
|
109
|
+
try {
|
|
110
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
111
|
+
} catch {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
for (const e of entries) {
|
|
115
|
+
const abs = path.join(dir, e.name);
|
|
116
|
+
if (e.isDirectory()) walkMarkdown(abs, out);
|
|
117
|
+
else if (e.isFile() && e.name.endsWith('.md')) out.push(abs);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface CatalogueAudit {
|
|
122
|
+
/** Empty when every projected tree is accounted for. */
|
|
123
|
+
findings: string[];
|
|
124
|
+
/** Top-level trees inspected — a zero here means the root moved. */
|
|
125
|
+
treesSeen: number;
|
|
126
|
+
/** Markdown files scanned for rule frontmatter outside the rules bucket. */
|
|
127
|
+
filesScanned: number;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Audit the projection for payload the census does not enumerate.
|
|
132
|
+
*
|
|
133
|
+
* Pure over the filesystem, and returns findings rather than throwing: the
|
|
134
|
+
* caller decides whether an unclassified tree is a refusal or a report, and
|
|
135
|
+
* the tests need to inspect the findings themselves.
|
|
136
|
+
*/
|
|
137
|
+
export function auditCatalogue(repoRoot: string): CatalogueAudit {
|
|
138
|
+
const rootAbs = path.join(repoRoot, PROJECTION_ROOT);
|
|
139
|
+
const findings: string[] = [];
|
|
140
|
+
const declared = declaredTopLevelDirs();
|
|
141
|
+
const onDemand = new Set(ON_DEMAND_TREES.map((t) => t.dir));
|
|
142
|
+
|
|
143
|
+
let dirs: fs.Dirent[];
|
|
144
|
+
try {
|
|
145
|
+
dirs = fs.readdirSync(rootAbs, { withFileTypes: true });
|
|
146
|
+
} catch {
|
|
147
|
+
return {
|
|
148
|
+
findings: [
|
|
149
|
+
`${PROJECTION_ROOT} could not be read. The payload catalogue cannot be audited against a ` +
|
|
150
|
+
'projection root that is not there — regenerate it (`task sync`) before trusting a ' +
|
|
151
|
+
'green from this gate.',
|
|
152
|
+
],
|
|
153
|
+
treesSeen: 0,
|
|
154
|
+
filesScanned: 0,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
let treesSeen = 0;
|
|
159
|
+
for (const d of dirs) {
|
|
160
|
+
if (!d.isDirectory()) continue;
|
|
161
|
+
treesSeen += 1;
|
|
162
|
+
if (declared.has(d.name) || onDemand.has(d.name)) continue;
|
|
163
|
+
findings.push(
|
|
164
|
+
`${PROJECTION_ROOT}/${d.name}/ is projected but classified by nothing. It is neither a declared ` +
|
|
165
|
+
'prefix-stable surface nor on the on-demand list, so the standing-payload census does not ' +
|
|
166
|
+
'measure it and no ceiling can see what it costs. Classify it: add it to ' +
|
|
167
|
+
'PREFIX_STABLE_SURFACES if a host loads it into standing context, or to ON_DEMAND_TREES ' +
|
|
168
|
+
'with the mechanism that keeps it out. Do not leave it unclassified — the whole point of ' +
|
|
169
|
+
'this check is that unclassified is the state nobody notices.',
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Rule-shaped payload outside the rules bucket.
|
|
174
|
+
const exempt = new Set(RULE_SHAPED_EXEMPT.map(normalise));
|
|
175
|
+
let filesScanned = 0;
|
|
176
|
+
for (const d of dirs) {
|
|
177
|
+
if (!d.isDirectory() || declared.has(d.name)) continue;
|
|
178
|
+
const files: string[] = [];
|
|
179
|
+
walkMarkdown(path.join(rootAbs, d.name), files);
|
|
180
|
+
for (const abs of files) {
|
|
181
|
+
const rel = normalise(path.relative(repoRoot, abs));
|
|
182
|
+
if (exempt.has(rel)) continue;
|
|
183
|
+
filesScanned += 1;
|
|
184
|
+
let head: string;
|
|
185
|
+
try {
|
|
186
|
+
// Frontmatter only — reading whole bodies over ~1,800 files is
|
|
187
|
+
// the difference between a gate people run and one they skip.
|
|
188
|
+
const fd = fs.openSync(abs, 'r');
|
|
189
|
+
const buf = Buffer.alloc(2048);
|
|
190
|
+
const n = fs.readSync(fd, buf, 0, 2048, 0);
|
|
191
|
+
fs.closeSync(fd);
|
|
192
|
+
head = buf.subarray(0, n).toString('utf-8');
|
|
193
|
+
} catch {
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
if (!head.startsWith('---')) continue;
|
|
197
|
+
const end = head.indexOf('\n---', 3);
|
|
198
|
+
const frontmatter = end === -1 ? head : head.slice(0, end);
|
|
199
|
+
if (RULE_TYPE_LINE.test(frontmatter)) {
|
|
200
|
+
findings.push(
|
|
201
|
+
`${rel} carries rule frontmatter but sits outside the measured rules bucket. A file the ` +
|
|
202
|
+
'router can deliver is standing payload whatever directory it is in, so this one costs ' +
|
|
203
|
+
'tokens the ceiling never sees. Move it under the rules surface, or — if it is a ' +
|
|
204
|
+
'scaffold that is delivered to nobody — add it to RULE_SHAPED_EXEMPT with that reason.',
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return { findings, treesSeen, filesScanned };
|
|
211
|
+
}
|