@event4u/agent-config 14.23.0 → 15.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 +198 -0
- 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 +1 -1
- 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 +1 -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/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/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-HZ52BRGG.js} +24 -18
- package/dist/cli-delegate/{chunk-6RJA2F5A.js → chunk-IVBPRCQO.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 +3 -3
- package/dist/cli-delegate/cmd_doctor.js +3 -3
- package/dist/cli-delegate/cmd_explain.js +2 -2
- package/dist/cli-delegate/cmd_export.js +4 -4
- package/dist/cli-delegate/cmd_handoff.js +4 -4
- 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 +2 -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 +1 -1
- 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 +41 -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 +22 -75
- 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 +8607 -8930
- package/dist/install/install.mjs +35 -8
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +1433 -1342
- 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/condense.js +2 -5
- package/dist/server/io/yamlIO.js +125 -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 +4 -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 +2 -3
- 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/_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/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/guidelines_lane.ts +164 -0
- package/src/scripts/_lib/obligation_frequency.ts +2 -3
- package/src/scripts/_lib/platform_anchor.ts +1053 -0
- package/src/scripts/_lib/ratification_artifact.ts +278 -0
- 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 +103 -37
- package/src/scripts/_lib/tolerance_shadow.ts +177 -0
- 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_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 +292 -4
- package/src/scripts/check_projected_rule_routes.ts +395 -0
- 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 +35 -27
- package/src/scripts/hooks/category_a.ts +1 -1
- package/src/scripts/hooks/chain_nudge_hook.ts +311 -25
- 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/ui_route_nudge_hook.ts +52 -15
- package/src/scripts/hot_context_hook.ts +41 -401
- package/src/scripts/lint_evidence_artifacts.ts +1 -0
- package/src/scripts/lint_knowledge_scale.ts +0 -26
- package/src/scripts/memory_lookup.ts +9 -9
- 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 +270 -10
- package/src/server/io/yamlIO.ts +127 -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
|
@@ -18,11 +18,37 @@
|
|
|
18
18
|
* a shape that cannot be written as an allowlist pattern at all. That class
|
|
19
19
|
* shrinks only by not writing it.
|
|
20
20
|
*
|
|
21
|
+
* THE SECOND CLASS, AND WHY IT BELONGS HERE. A Bash command that writes a
|
|
22
|
+
* file — `sed -i`, `cat > f`, `tee f`, `perl -i`, a `python3 -c` that opens a
|
|
23
|
+
* path for writing — costs a confirmation for a reason no allowlist entry
|
|
24
|
+
* fixes: a write-shaped Bash grant does NOT persist. The host's own
|
|
25
|
+
* permission documentation records that "don't ask again" saves a permanent
|
|
26
|
+
* rule for read-only and pre-approved commands and that write-shaped ones
|
|
27
|
+
* last until session end, so the same shape is confirmed again next session.
|
|
28
|
+
* The Edit and Write tools carry no such expiry for a path inside the working
|
|
29
|
+
* directory. That makes the substitution a strictly cheaper primitive rather
|
|
30
|
+
* than a style preference, which is why the concern that already reads
|
|
31
|
+
* `tool_input.command` carries it instead of a second concern reading the
|
|
32
|
+
* same field. Measured on 2026-09-10 over 7,569 distinct real Bash calls in
|
|
33
|
+
* 39 transcripts on the maintainer's machine: 306 (4.0 %) wrote a file
|
|
34
|
+
* through the shell — 216 `cat >`, 66 `sed -i`, 16 `python3 -c` with a
|
|
35
|
+
* write-mode `open`, 7 `perl -i`, 1 `tee`. Recompute with
|
|
36
|
+
* `./scripts-run src/scripts/autonomy_friction_traffic`, which shares these
|
|
37
|
+
* detectors; every figure in this change comes from that one run.
|
|
38
|
+
*
|
|
39
|
+
* THE COUNT IS A FLOOR, and the five rules are why. `echo >`, `printf >`,
|
|
40
|
+
* `jq >`, `awk >`, `git show >` and `cp` all fill a file and none is matched:
|
|
41
|
+
* the list is positive by design, and a generic redirect scanner would fire on
|
|
42
|
+
* `grep x f > out.txt`, where the shell is not the thing doing the writing.
|
|
43
|
+
* A heredoc whose BODY performs the write is invisible for the same reason the
|
|
44
|
+
* body is stripped at all. Read 4.0 % as "at least".
|
|
45
|
+
*
|
|
21
46
|
* WHAT IT DOES NOT FLAG, DELIBERATELY. A pipe of ordinary filters
|
|
22
47
|
* (`grep foo file | head`) is one command with a filter, not two work steps.
|
|
23
|
-
* A redirect
|
|
24
|
-
*
|
|
25
|
-
* nudge noise, and a nudge that fires on
|
|
48
|
+
* A redirect whose target is not a file the shell is filling with content —
|
|
49
|
+
* `2>&1`, `> /dev/null` — is not a write. A heredoc is a command with input.
|
|
50
|
+
* Flagging any of those would make the nudge noise, and a nudge that fires on
|
|
51
|
+
* correct usage is worse than none.
|
|
26
52
|
*
|
|
27
53
|
* NEVER BLOCKS. The dispatcher contract is 0 allow · 2 warn, and a warn on
|
|
28
54
|
* `pre_tool_use` with `severity: advisory` is an injection, not a deny — the
|
|
@@ -30,10 +56,23 @@
|
|
|
30
56
|
* failure path returns allow: unreadable stdin, malformed JSON, unwritable
|
|
31
57
|
* latch. A token optimisation must never break a tool call.
|
|
32
58
|
*
|
|
33
|
-
* ONCE PER SESSION. A latch keyed by session id, in the state
|
|
34
|
-
* `code-graph-nudge.json` already occupies.
|
|
35
|
-
* once, early, on the first
|
|
36
|
-
*
|
|
59
|
+
* ONCE PER SHAPE CLASS PER SESSION. A latch keyed by session id, in the state
|
|
60
|
+
* directory `code-graph-nudge.json` already occupies. Each class reaches the
|
|
61
|
+
* model once, early, on the first call carrying it — so a session sees at most
|
|
62
|
+
* two lines, never one line for two different mistakes.
|
|
63
|
+
*
|
|
64
|
+
* That is a per-CLASS latch, not a per-CALL one, and the distinction is the
|
|
65
|
+
* whole reason it is allowed to change: the recorded decision this file
|
|
66
|
+
* carried refuses "repeating it every call", which is the nagging this
|
|
67
|
+
* codebase refuses elsewhere, and a second class firing once is a different
|
|
68
|
+
* mechanism from a first class firing twice. The single-boolean latch was
|
|
69
|
+
* written when there was one class; with two, it would have let whichever
|
|
70
|
+
* shape came first silence the other for the rest of the session.
|
|
71
|
+
*
|
|
72
|
+
* A latch file written by the single-class version holds `true` rather than an
|
|
73
|
+
* object. That is read as "the chain class has fired", which is what it meant,
|
|
74
|
+
* so an in-flight session upgrades without losing its latch and without
|
|
75
|
+
* replaying a line it already showed.
|
|
37
76
|
*
|
|
38
77
|
* ON BY DEFAULT, WITH AN OPT-OUT. Unlike `code-graph-nudge`, which gates on a
|
|
39
78
|
* project capability that may not exist, the fact this nudge carries is a
|
|
@@ -137,14 +176,208 @@ export function stripLiterals(cmd: string): string {
|
|
|
137
176
|
return out;
|
|
138
177
|
}
|
|
139
178
|
|
|
179
|
+
/**
|
|
180
|
+
* Heredoc BODIES removed, the command line they sit on kept.
|
|
181
|
+
*
|
|
182
|
+
* `stripLiterals` runs from `<<` to the closing tag and so deletes the redirect
|
|
183
|
+
* that shares the command line; leaving the body in instead let a heredoc that
|
|
184
|
+
* merely MENTIONS a write shape fire the nudge and spend the session's one
|
|
185
|
+
* write line. Neither view is right for the write rules, so this is the third:
|
|
186
|
+
* the marker and the rest of the command line survive, the body does not.
|
|
187
|
+
*
|
|
188
|
+
* Consequence, stated because it is a real false negative: a heredoc whose BODY
|
|
189
|
+
* performs the write — `python3 - <<PY` opening a path — is invisible here. The
|
|
190
|
+
* class is a floor, and this is one of the reasons.
|
|
191
|
+
*/
|
|
192
|
+
export function stripHeredocBodies(cmd: string): string {
|
|
193
|
+
const marker = /<<-?\s*(['"]?)([A-Za-z_][A-Za-z0-9_]*)\1/g;
|
|
194
|
+
let out = '';
|
|
195
|
+
let cursor = 0;
|
|
196
|
+
let m: RegExpExecArray | null;
|
|
197
|
+
while ((m = marker.exec(cmd)) !== null) {
|
|
198
|
+
const tag = m[2] as string;
|
|
199
|
+
const nl = cmd.indexOf('\n', m.index + m[0].length);
|
|
200
|
+
if (nl === -1) break;
|
|
201
|
+
const close = cmd.indexOf(`\n${tag}`, nl);
|
|
202
|
+
const end = close === -1 ? cmd.length : close + tag.length + 1;
|
|
203
|
+
out += cmd.slice(cursor, m.index) + '<<' + cmd.slice(m.index + m[0].length, nl);
|
|
204
|
+
cursor = end;
|
|
205
|
+
marker.lastIndex = end;
|
|
206
|
+
}
|
|
207
|
+
return out + cmd.slice(cursor);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Quoted spans removed, heredoc bodies LEFT IN PLACE.
|
|
212
|
+
*
|
|
213
|
+
* The sibling of `stripLiterals` for the write rules. That one must consume a
|
|
214
|
+
* heredoc, because an operator in its body is not chaining; this one must not,
|
|
215
|
+
* because the heredoc marker and the redirect share a command line and
|
|
216
|
+
* consuming to the closing tag takes the redirect with it.
|
|
217
|
+
*/
|
|
218
|
+
export function stripQuoted(cmd: string): string {
|
|
219
|
+
let out = '';
|
|
220
|
+
let i = 0;
|
|
221
|
+
let quote: string | null = null;
|
|
222
|
+
while (i < cmd.length) {
|
|
223
|
+
const c = cmd[i] as string;
|
|
224
|
+
if (quote) {
|
|
225
|
+
if (c === '\\' && quote === '"') {
|
|
226
|
+
i += 2;
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
if (c === quote) quote = null;
|
|
230
|
+
i += 1;
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (c === '\\') {
|
|
234
|
+
i += 2;
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
if (c === '"' || c === "'") {
|
|
238
|
+
quote = c;
|
|
239
|
+
i += 1;
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
out += c;
|
|
243
|
+
i += 1;
|
|
244
|
+
}
|
|
245
|
+
return out;
|
|
246
|
+
}
|
|
247
|
+
|
|
140
248
|
/** What the nudge saw, or null when the command is not chained work. */
|
|
141
249
|
export function detectChaining(command: string): string | null {
|
|
142
|
-
|
|
250
|
+
return _detectChaining(stripLiterals(command));
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function _detectChaining(bare: string): string | null {
|
|
143
254
|
if (/^\s*[A-Za-z_][A-Za-z0-9_]*=/.test(bare) && /[;\n]/.test(bare)) {
|
|
144
255
|
return 'a leading `VAR=…` assignment carrying state into a later segment';
|
|
145
256
|
}
|
|
146
257
|
if (/&&|\|\|/.test(bare)) return 'work steps chained with `&&` / `||`';
|
|
147
258
|
if (/;\s*\S/.test(bare)) return 'work steps chained with `;`';
|
|
259
|
+
// The header names newlines among the host's split points and this rule did
|
|
260
|
+
// not read them, so `git status\ngit diff` — two work steps by any reading —
|
|
261
|
+
// was silent. Heredoc bodies are already gone from this view, so a
|
|
262
|
+
// multi-line heredoc command does not reach here.
|
|
263
|
+
if (/\n\s*\S/.test(bare)) return 'work steps separated by a newline';
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* The five shapes that fill a file's content from the shell, each matched on
|
|
269
|
+
* the literal-stripped command so a quoted mention cannot fire it.
|
|
270
|
+
*
|
|
271
|
+
* A positive list, not a redirect scan: `>` alone is a redirect and the header
|
|
272
|
+
* says a redirect is not flagged. What is flagged is a command whose named
|
|
273
|
+
* operation IS "put this content in that path", which is the operation Edit
|
|
274
|
+
* and Write perform without an expiring grant. `/dev/null` and an fd
|
|
275
|
+
* duplication (`2>&1`) are excluded because neither names a file being filled.
|
|
276
|
+
*/
|
|
277
|
+
const EDIT_BY_SHELL: ReadonlyArray<{ re: RegExp; seen: string }> = [
|
|
278
|
+
// `-i` may ride inside a flag cluster (`-ri`, `-Ei`) or carry a backup
|
|
279
|
+
// suffix (`-i.bak`), so the letter is matched inside the cluster rather
|
|
280
|
+
// than as a token. `sed -n 2,8p` and `sed -e s/a/b/ f` have no `i` in any
|
|
281
|
+
// flag and stay silent; `--expression=…` cannot match because the class
|
|
282
|
+
// admits letters only after the single leading dash.
|
|
283
|
+
{
|
|
284
|
+
re: /(^|[\s;&|(])sed\s+(?:-\S+\s+)*-(?:i|[nersuzE]*i[nersuzE]*|-in-place)(?:\.\S+)?(?=\s|$)/,
|
|
285
|
+
seen: '`sed -i` edits a file in place',
|
|
286
|
+
},
|
|
287
|
+
// The letter set is closed on purpose. Matching an `i` ANYWHERE in a flag
|
|
288
|
+
// cluster made `perl -Mstrict`, `perl -MList::Util` and `perl -Ilib` all
|
|
289
|
+
// report an in-place edit — the letters after `-M` and `-I` are a module
|
|
290
|
+
// name and a directory, not switches. Only perl's own one-letter switches
|
|
291
|
+
// may share the cluster with `i`.
|
|
292
|
+
{
|
|
293
|
+
re: /(^|[\s;&|(])perl\s+(?:-\S+\s+)*-(?:i|[pnlaw]*i[pnlaw]*)(?:\.\S+)?(?=\s|$)/,
|
|
294
|
+
seen: '`perl -i` edits a file in place',
|
|
295
|
+
},
|
|
296
|
+
// `[^\n]*` between the head and the redirect, so `cat <<'EOF' > out.txt`
|
|
297
|
+
// and `cat a b > merged` both land, while `> /dev/null` and an fd
|
|
298
|
+
// duplication (`2>&1`) are excluded by the lookahead at every position the
|
|
299
|
+
// engine tries.
|
|
300
|
+
// `[^\n|;&]*` — the redirect must belong to the SAME simple command. With
|
|
301
|
+
// `[^\n]*` this rule was a general redirect scanner for any cat-headed
|
|
302
|
+
// pipeline, so `cat f | grep x > out.txt` fired while the identical
|
|
303
|
+
// `grep x f > out.txt` stayed silent, which its own "positive list, not a
|
|
304
|
+
// redirect scan" comment forbids.
|
|
305
|
+
{ re: /(^|[\s;&|(])cat\b[^\n|;&]*>{1,2}\s*(?!&|\/dev\/null)\S/, seen: '`cat >` fills a file from the shell' },
|
|
306
|
+
// A flag cluster before the path is normal (`tee -a out.txt`), and the path
|
|
307
|
+
// is REQUIRED. Dropping the original `(?!-)` lookahead to admit the flagged
|
|
308
|
+
// form turned a false negative into a false-positive class: `tee -a`,
|
|
309
|
+
// `foo | tee | wc -l`, `foo | tee -` and `tee -a /dev/null` all fired. The
|
|
310
|
+
// path token is therefore matched explicitly — not a flag, not a shell
|
|
311
|
+
// operator, not the null device.
|
|
312
|
+
{
|
|
313
|
+
re: /(^|[\s;&|(])tee\s+(?:-[A-Za-z]+\s+)*(?!\/dev\/null)[^-\s;&|<>][^\s;&|<>]*/,
|
|
314
|
+
seen: '`tee` writes its input to a file',
|
|
315
|
+
},
|
|
316
|
+
];
|
|
317
|
+
|
|
318
|
+
/** The interpreter form, split across the two views for the reason below. */
|
|
319
|
+
const PY_AT_COMMAND_POSITION = /(^|[\s;&|(])python3?\s+-c\b/;
|
|
320
|
+
const PY_OPENS_FOR_WRITING = /\bopen\s*\([^)]*['"][wax]\+?['"]/;
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* What the write-shaped detector saw, or null when the call writes no file.
|
|
324
|
+
*
|
|
325
|
+
* `stripQuoted` rather than `stripLiterals` for the redirect rules: the
|
|
326
|
+
* heredoc branch of `stripLiterals` runs to the closing tag and swallows the
|
|
327
|
+
* command line with it, so `cat <<'EOF' > out.txt` lost its own redirect and
|
|
328
|
+
* the largest measured write shape went undetected in its most common spelling.
|
|
329
|
+
*
|
|
330
|
+
* The interpreter rule reads BOTH views, and needs to. Its program is a quoted
|
|
331
|
+
* argument, so the write mode is only visible in the raw string; but matching
|
|
332
|
+
* the raw string alone fires on any command that merely QUOTES the shape —
|
|
333
|
+
* `git commit -m "use python3 -c open(p,'w')"` did, and this change ships that
|
|
334
|
+
* exact string in a substitution table. So the interpreter must sit at a
|
|
335
|
+
* command position in the STRIPPED text, where a quoted mention has already
|
|
336
|
+
* been removed, and the write mode must be named in the RAW text.
|
|
337
|
+
*/
|
|
338
|
+
export function detectEditByShell(command: string): string | null {
|
|
339
|
+
return _detectEditByShell(command, writeView(command));
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/** The view the write rules read: no heredoc bodies, no quoted spans. */
|
|
343
|
+
export function writeView(command: string): string {
|
|
344
|
+
return stripQuoted(stripHeredocBodies(command));
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function _detectEditByShell(command: string, quotesStripped: string): string | null {
|
|
348
|
+
for (const shape of EDIT_BY_SHELL) {
|
|
349
|
+
if (shape.re.test(quotesStripped)) return shape.seen;
|
|
350
|
+
}
|
|
351
|
+
if (PY_AT_COMMAND_POSITION.test(quotesStripped) && PY_OPENS_FOR_WRITING.test(command)) {
|
|
352
|
+
return 'a `python3 -c` one-liner opens a path for writing';
|
|
353
|
+
}
|
|
354
|
+
return null;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/** The two shape classes this concern carries. */
|
|
358
|
+
export type NudgeClass = 'edit-by-shell' | 'chain';
|
|
359
|
+
|
|
360
|
+
/** One finding: which class fired, and what it saw. */
|
|
361
|
+
export interface NudgeFinding {
|
|
362
|
+
klass: NudgeClass;
|
|
363
|
+
seen: string;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* The finding for this command, or null.
|
|
368
|
+
*
|
|
369
|
+
* `edit-by-shell` is tested first, and on a call that is both — `cd d && sed
|
|
370
|
+
* -i … f` is — it wins: its line names a primitive that costs no confirmation
|
|
371
|
+
* at all, while the chain line only explains why this one did.
|
|
372
|
+
*/
|
|
373
|
+
export function detectShape(command: string): NudgeFinding | null {
|
|
374
|
+
// Each view is built once. This runs on every shell tool call and the
|
|
375
|
+
// header documents 26 ms p95 as load-bearing, so calling the two exported
|
|
376
|
+
// wrappers here would strip the same string twice per call for nothing.
|
|
377
|
+
const write = _detectEditByShell(command, writeView(command));
|
|
378
|
+
if (write) return { klass: 'edit-by-shell', seen: write };
|
|
379
|
+
const chained = _detectChaining(stripLiterals(command));
|
|
380
|
+
if (chained) return { klass: 'chain', seen: chained };
|
|
148
381
|
return null;
|
|
149
382
|
}
|
|
150
383
|
|
|
@@ -190,25 +423,59 @@ function latchFile(root: string): string {
|
|
|
190
423
|
return path.join(root, 'agents', 'runtime', 'state', 'chain-nudge.json');
|
|
191
424
|
}
|
|
192
425
|
|
|
193
|
-
|
|
426
|
+
/** One session's latch: the object form, or the pre-two-class `true`. */
|
|
427
|
+
type LatchEntry = boolean | Record<string, boolean>;
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Has `klass` already fired for this session?
|
|
431
|
+
*
|
|
432
|
+
* A legacy `true` is read as the chain class having fired, which is what the
|
|
433
|
+
* single-class version wrote it to mean. The write class is then unlatched in
|
|
434
|
+
* that session and gets its first line — correct, because it never had one.
|
|
435
|
+
*/
|
|
436
|
+
export function classAlreadyNudged(entry: LatchEntry | undefined, klass: NudgeClass): boolean {
|
|
437
|
+
if (entry === true) return klass === 'chain';
|
|
438
|
+
if (isObject(entry)) return entry[klass] === true;
|
|
439
|
+
return false;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/** `klass` recorded on top of whatever the entry already held. */
|
|
443
|
+
export function withClassLatched(entry: LatchEntry | undefined, klass: NudgeClass): Record<string, boolean> {
|
|
444
|
+
const next: Record<string, boolean> = entry === true ? { chain: true } : isObject(entry) ? { ...(entry as Record<string, boolean>) } : {};
|
|
445
|
+
next[klass] = true;
|
|
446
|
+
return next;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* The latch state, or `{}` for anything that is not a JSON object.
|
|
451
|
+
*
|
|
452
|
+
* The shape check is not decoration. `JSON.parse` returns `null` for a latch
|
|
453
|
+
* file holding `null` and a number for one holding `7`, neither of which throws
|
|
454
|
+
* — so the try/catch alone let a corrupted file reach the caller as a non-object
|
|
455
|
+
* and crash the property read. The helper this replaced guarded that by reading
|
|
456
|
+
* the property inside its own try; consolidating the read dropped the guard, and
|
|
457
|
+
* the header's "every failure path returns allow" stopped being true.
|
|
458
|
+
*/
|
|
459
|
+
function readLatch(root: string): Record<string, LatchEntry> {
|
|
194
460
|
try {
|
|
195
|
-
const
|
|
196
|
-
return
|
|
461
|
+
const parsed: unknown = JSON.parse(fs.readFileSync(latchFile(root), 'utf-8'));
|
|
462
|
+
return isObject(parsed as JsonValue) ? (parsed as Record<string, LatchEntry>) : {};
|
|
197
463
|
} catch {
|
|
198
|
-
return
|
|
464
|
+
return {};
|
|
199
465
|
}
|
|
200
466
|
}
|
|
201
467
|
|
|
202
|
-
|
|
468
|
+
/**
|
|
469
|
+
* Record `klass` into an ALREADY-READ state and persist it.
|
|
470
|
+
*
|
|
471
|
+
* The state is passed in rather than re-read: the caller has just consulted it
|
|
472
|
+
* to decide whether to fire, and reading the same file twice per firing call is
|
|
473
|
+
* the kind of hot-path waste this file's own ordering comment exists to avoid.
|
|
474
|
+
*/
|
|
475
|
+
function latch(root: string, session: string, klass: NudgeClass, state: Record<string, LatchEntry>): void {
|
|
203
476
|
try {
|
|
204
477
|
const p = latchFile(root);
|
|
205
|
-
|
|
206
|
-
try {
|
|
207
|
-
state = JSON.parse(fs.readFileSync(p, 'utf-8')) as Record<string, boolean>;
|
|
208
|
-
} catch {
|
|
209
|
-
/* fresh */
|
|
210
|
-
}
|
|
211
|
-
state[session] = true;
|
|
478
|
+
state[session] = withClassLatched(state[session], klass);
|
|
212
479
|
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
213
480
|
fs.writeFileSync(p, JSON.stringify(state));
|
|
214
481
|
} catch {
|
|
@@ -216,6 +483,24 @@ function latch(root: string, session: string): void {
|
|
|
216
483
|
}
|
|
217
484
|
}
|
|
218
485
|
|
|
486
|
+
/** The write-shape line — names the expiry, then the primitive without one. */
|
|
487
|
+
export function editByShellReason(seen: string): string {
|
|
488
|
+
return (
|
|
489
|
+
`This Bash call writes a file through the shell: ${seen}. A write-shaped ` +
|
|
490
|
+
'Bash grant does not persist — the host saves a permanent rule for ' +
|
|
491
|
+
'read-only commands, while a write-shaped one lasts until session end, so ' +
|
|
492
|
+
'this same shape costs another confirmation next session. Edit and Write ' +
|
|
493
|
+
'carry no such expiry inside the working directory: Edit for a targeted ' +
|
|
494
|
+
'change, Write for a new file, the shell for reads. ' +
|
|
495
|
+
'See `token-efficiency` § One command per Bash call.'
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/** The line for a finding, dispatched on its class. */
|
|
500
|
+
export function reasonFor(finding: NudgeFinding): string {
|
|
501
|
+
return finding.klass === 'edit-by-shell' ? editByShellReason(finding.seen) : nudgeReason(finding.seen);
|
|
502
|
+
}
|
|
503
|
+
|
|
219
504
|
/** The nudge line — one line, names what was seen and what to do instead. */
|
|
220
505
|
export function nudgeReason(seen: string): string {
|
|
221
506
|
return (
|
|
@@ -247,8 +532,8 @@ export function main(): number {
|
|
|
247
532
|
const command = bashCommand(envelope);
|
|
248
533
|
if (!command) return EXIT_ALLOW;
|
|
249
534
|
|
|
250
|
-
const
|
|
251
|
-
if (!
|
|
535
|
+
const finding = detectShape(command);
|
|
536
|
+
if (!finding) return EXIT_ALLOW;
|
|
252
537
|
|
|
253
538
|
const cwd = envelope['cwd'];
|
|
254
539
|
const pr = envelope['workspace_root'] ?? envelope['project_root'];
|
|
@@ -256,10 +541,11 @@ export function main(): number {
|
|
|
256
541
|
if (!enabled(root)) return EXIT_ALLOW;
|
|
257
542
|
|
|
258
543
|
const session = sessionId(envelope);
|
|
259
|
-
|
|
544
|
+
const state = readLatch(root);
|
|
545
|
+
if (classAlreadyNudged(state[session], finding.klass)) return EXIT_ALLOW;
|
|
260
546
|
|
|
261
|
-
latch(root, session);
|
|
262
|
-
process.stdout.write(`${JSON.stringify({ decision: 'warn', reason:
|
|
547
|
+
latch(root, session, finding.klass, state);
|
|
548
|
+
process.stdout.write(`${JSON.stringify({ decision: 'warn', reason: reasonFor(finding) })}\n`);
|
|
263
549
|
return EXIT_WARN;
|
|
264
550
|
}
|
|
265
551
|
|