avorelo 0.3.8 → 0.4.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +16 -23
- package/README.md +62 -72
- package/bin/avorelo +9 -0
- package/package.json +147 -139
- package/scripts/README.md +40 -0
- package/scripts/avorelo-session-collision-guard.js +540 -0
- package/scripts/avorelo-workstream-preflight.js +918 -0
- package/scripts/cco-dashboard.js +346 -0
- package/scripts/cco-posttooluse.js +504 -0
- package/scripts/cco-pretooluse.js +381 -0
- package/scripts/cco-status.js +540 -0
- package/scripts/cco-stop.js +77 -0
- package/scripts/cco-userprompt-submit.js +83 -0
- package/scripts/lib/activation/account-state.js +37 -0
- package/scripts/lib/activation/activate-command.js +114 -0
- package/scripts/lib/activation/activation-runner.js +607 -0
- package/scripts/lib/activation/activation-self-healing.js +481 -0
- package/scripts/lib/activation/activation-state.js +96 -0
- package/scripts/lib/activation/activation-summary.js +241 -0
- package/scripts/lib/activation/adapters/claude-code.js +77 -0
- package/scripts/lib/activation/adapters/codex-cli.js +52 -0
- package/scripts/lib/activation/adapters/cursor.js +37 -0
- package/scripts/lib/activation/adapters/github-agent.js +39 -0
- package/scripts/lib/activation/adapters/terminal.js +42 -0
- package/scripts/lib/activation/adapters/vscode.js +39 -0
- package/scripts/lib/activation/adapters/windsurf.js +37 -0
- package/scripts/lib/activation/ai-surface-detector.js +151 -0
- package/scripts/lib/activation/connect-account.js +145 -0
- package/scripts/lib/activation/detect-environment.js +75 -0
- package/scripts/lib/activation/detect-hosts.js +62 -0
- package/scripts/lib/activation/format-activation-output.js +109 -0
- package/scripts/lib/activation/next-action.js +43 -0
- package/scripts/lib/activation/repair-engine.js +219 -0
- package/scripts/lib/activation/run-entry.js +346 -0
- package/scripts/lib/activation-distribution-readiness.js +507 -0
- package/scripts/lib/adapter-conformance.js +176 -0
- package/scripts/lib/adapter-readiness.js +428 -0
- package/scripts/lib/adapter-safety-boundaries.js +335 -0
- package/scripts/lib/adapter-technical-readiness-gate.js +205 -0
- package/scripts/lib/agent-access-governance.js +455 -0
- package/scripts/lib/agent-activation-readiness.js +878 -0
- package/scripts/lib/agent-enforcement.js +765 -0
- package/scripts/lib/agent-evolution-loop.js +479 -0
- package/scripts/lib/agent-policy-profile.js +210 -0
- package/scripts/lib/agent-security/action-evaluator.js +507 -0
- package/scripts/lib/agent-security/adapter-registry.js +98 -0
- package/scripts/lib/agent-security/auto-policy.js +139 -0
- package/scripts/lib/agent-security/bounded-scan.js +93 -0
- package/scripts/lib/agent-security/enforcement-adapter.js +174 -0
- package/scripts/lib/agent-security/enforcement-engine.js +1129 -0
- package/scripts/lib/agent-security/file-write-adapter.js +183 -0
- package/scripts/lib/agent-security/file-write-rules.js +178 -0
- package/scripts/lib/agent-security/index.js +3342 -0
- package/scripts/lib/agent-security/instruction-risk.js +181 -0
- package/scripts/lib/agent-security/mcp-action-adapter.js +185 -0
- package/scripts/lib/agent-security/mcp-action-rules.js +184 -0
- package/scripts/lib/agent-security/package-action-adapter.js +175 -0
- package/scripts/lib/agent-security/package-action-rules.js +233 -0
- package/scripts/lib/agent-security/performance.js +148 -0
- package/scripts/lib/agent-security/permission-minimizer.js +403 -0
- package/scripts/lib/agent-security/scan-cache.js +74 -0
- package/scripts/lib/agent-security/source-trust.js +146 -0
- package/scripts/lib/ai-efficiency-dogfood-pack.js +437 -0
- package/scripts/lib/ai-efficiency-eval.js +207 -0
- package/scripts/lib/ai-efficiency-guard-contract.js +209 -0
- package/scripts/lib/ai-efficiency-measured-value.js +106 -0
- package/scripts/lib/ai-install-prompt.js +293 -0
- package/scripts/lib/ai-task-inference.js +155 -0
- package/scripts/lib/ai-value-ledger.js +121 -0
- package/scripts/lib/ai-value-proof-table.js +151 -0
- package/scripts/lib/ai-work-efficiency-routing.js +623 -0
- package/scripts/lib/ai-workspace-hygiene.js +1499 -0
- package/scripts/lib/alpha-activation.js +520 -0
- package/scripts/lib/alpha-feedback.js +263 -0
- package/scripts/lib/alpha-readiness-gate.js +332 -0
- package/scripts/lib/anti-gaming.js +169 -0
- package/scripts/lib/artifact-health.js +431 -0
- package/scripts/lib/artifact-receipt-hygiene.js +619 -0
- package/scripts/lib/attribution.js +180 -0
- package/scripts/lib/audit.js +289 -0
- package/scripts/lib/avorelo-skill-registry.js +810 -0
- package/scripts/lib/batch-jobs.js +71 -0
- package/scripts/lib/brain-pack.js +578 -0
- package/scripts/lib/brand-boundary.js +424 -0
- package/scripts/lib/brand.js +74 -0
- package/scripts/lib/browser-capability.js +1048 -0
- package/scripts/lib/browser-proof-governed-workflow.js +1020 -0
- package/scripts/lib/browser-proof-preflight.js +321 -0
- package/scripts/lib/cache-readiness.js +296 -0
- package/scripts/lib/canonical-reentry.js +162 -0
- package/scripts/lib/capability-contract-validator.js +177 -0
- package/scripts/lib/capability-hygiene.js +504 -0
- package/scripts/lib/capability-intake-quarantine.js +789 -0
- package/scripts/lib/capability-kernel-registry.js +566 -0
- package/scripts/lib/capability-kernel.js +202 -0
- package/scripts/lib/capability-manifest.js +255 -0
- package/scripts/lib/capability-outcome-normalizer.js +104 -0
- package/scripts/lib/capability-packs.js +314 -0
- package/scripts/lib/capability-recommender.js +513 -0
- package/scripts/lib/capability-registry.js +1062 -0
- package/scripts/lib/carry-forward-surfacing.js +194 -0
- package/scripts/lib/ccusage-adapter.js +188 -0
- package/scripts/lib/claude-session-evidence/index.js +1027 -0
- package/scripts/lib/cli-output-sanitizer.js +118 -0
- package/scripts/lib/company-loop.js +1149 -0
- package/scripts/lib/config.js +641 -0
- package/scripts/lib/context-acquisition-plan.js +359 -0
- package/scripts/lib/context-authority-rules.js +138 -0
- package/scripts/lib/context-budget-guard.js +170 -0
- package/scripts/lib/context-budget-scanner.js +257 -0
- package/scripts/lib/context-budget.js +167 -0
- package/scripts/lib/context-claim-safety.js +116 -0
- package/scripts/lib/context-compiler.js +236 -0
- package/scripts/lib/context-optimizer.js +715 -0
- package/scripts/lib/context-packet.js +121 -0
- package/scripts/lib/context-receipt.js +57 -0
- package/scripts/lib/context-reduction-plan.js +179 -0
- package/scripts/lib/context-safety.js +88 -0
- package/scripts/lib/context-savings-engine.js +158 -0
- package/scripts/lib/context-source-registry.js +393 -0
- package/scripts/lib/context-task-profiles.js +147 -0
- package/scripts/lib/cost-abuse-guard.js +975 -0
- package/scripts/lib/cost-evidence.js +287 -0
- package/scripts/lib/cost-to-outcome-signals.js +639 -0
- package/scripts/lib/cross-host-install-plan.js +308 -0
- package/scripts/lib/cross-host-install-readiness.js +242 -0
- package/scripts/lib/cross-host-value-flow.js +268 -0
- package/scripts/lib/dashboard.js +1056 -0
- package/scripts/lib/data-permissions-guard.js +1187 -0
- package/scripts/lib/deployment-environment-guard.js +1236 -0
- package/scripts/lib/design-partner-feedback.js +346 -0
- package/scripts/lib/dogfood-evidence-freshness.js +567 -0
- package/scripts/lib/efficiency-receipt.js +354 -0
- package/scripts/lib/entitlements.js +100 -0
- package/scripts/lib/execution-packet.js +559 -0
- package/scripts/lib/execution-route-governor.js +179 -0
- package/scripts/lib/experimentation-events.js +547 -0
- package/scripts/lib/external-capability-compliance.js +107 -0
- package/scripts/lib/external-readiness/ai-visibility/ai-visibility-runner.js +322 -0
- package/scripts/lib/external-readiness/calibration/benchmark-site-catalog.js +121 -0
- package/scripts/lib/external-readiness/calibration/completion-gate.js +112 -0
- package/scripts/lib/external-readiness/calibration/real-site-benchmark-runner.js +284 -0
- package/scripts/lib/external-readiness/drift-detector.js +100 -0
- package/scripts/lib/external-readiness/endpoint-prober.js +332 -0
- package/scripts/lib/external-readiness/external-readiness-runner.js +112 -0
- package/scripts/lib/external-readiness/full-agent-readiness-scorer.js +220 -0
- package/scripts/lib/external-readiness/golden-path-runner.js +333 -0
- package/scripts/lib/external-readiness/inside-out-runner.js +118 -0
- package/scripts/lib/external-readiness/proof-receipt-writer.js +112 -0
- package/scripts/lib/external-readiness/safe-fix-executor.js +117 -0
- package/scripts/lib/external-readiness/skills/category-boundary-guard.js +30 -0
- package/scripts/lib/external-readiness/skills/pmm-positioning-guard.js +69 -0
- package/scripts/lib/external-readiness/skills/safe-fix-policy.js +35 -0
- package/scripts/lib/external-user-simulation.js +166 -0
- package/scripts/lib/failure-recovery-readiness.js +81 -0
- package/scripts/lib/failure-recovery.js +419 -0
- package/scripts/lib/feedback-intelligence.js +537 -0
- package/scripts/lib/feedback-signals.js +205 -0
- package/scripts/lib/file-integrity.js +68 -0
- package/scripts/lib/fsx.js +129 -0
- package/scripts/lib/full-readiness-gate.js +451 -0
- package/scripts/lib/governed-action-exposure-primitives.js +1514 -0
- package/scripts/lib/governed-exposure-planner.js +186 -0
- package/scripts/lib/governed-workspace-hygiene.js +946 -0
- package/scripts/lib/guard-suite-common.js +412 -0
- package/scripts/lib/guidance-builder.js +174 -0
- package/scripts/lib/hook-apply.js +1075 -0
- package/scripts/lib/hook-baseline.js +310 -0
- package/scripts/lib/hook-config-preview.js +275 -0
- package/scripts/lib/hook-contracts.js +290 -0
- package/scripts/lib/hook-safety-boundary-readiness.js +80 -0
- package/scripts/lib/host-capability-matrix.js +351 -0
- package/scripts/lib/host-support-context.js +254 -0
- package/scripts/lib/http-hook-action.js +538 -0
- package/scripts/lib/install-ai-readiness.js +84 -0
- package/scripts/lib/install-intake-risk.js +1051 -0
- package/scripts/lib/install-journey-intelligence.js +329 -0
- package/scripts/lib/intervention-guidance.js +57 -0
- package/scripts/lib/known-limitations.js +115 -0
- package/scripts/lib/l8-path-truth.js +146 -0
- package/scripts/lib/launch-hardening-gate.js +436 -0
- package/scripts/lib/launch-readiness.js +635 -0
- package/scripts/lib/learning-experimentation-foundation.js +1484 -0
- package/scripts/lib/learning-memory.js +686 -0
- package/scripts/lib/lifecycle-hooks.js +982 -0
- package/scripts/lib/local-package-smoke.js +436 -0
- package/scripts/lib/local-pricing.js +299 -0
- package/scripts/lib/mcp-enforcement.js +311 -0
- package/scripts/lib/mcp-least-privilege-policy.js +303 -0
- package/scripts/lib/mcp-tool-inventory.js +388 -0
- package/scripts/lib/mcp-tool-risk.js +0 -0
- package/scripts/lib/memory.js +335 -0
- package/scripts/lib/metrics.js +699 -0
- package/scripts/lib/micro-proof.js +133 -0
- package/scripts/lib/model-work-class-routing.js +79 -0
- package/scripts/lib/next-run-context.js +436 -0
- package/scripts/lib/next-run-continuity.js +1207 -0
- package/scripts/lib/observability-recovery-guard.js +1030 -0
- package/scripts/lib/operating-value.js +1662 -0
- package/scripts/lib/optimization-v3.js +122 -0
- package/scripts/lib/orchestration/adapters/_shared.js +49 -0
- package/scripts/lib/orchestration/adapters/aider.js +18 -0
- package/scripts/lib/orchestration/adapters/claude-code.js +35 -0
- package/scripts/lib/orchestration/adapters/codex.js +35 -0
- package/scripts/lib/orchestration/adapters/gemini-cli.js +18 -0
- package/scripts/lib/orchestration/adapters/git.js +25 -0
- package/scripts/lib/orchestration/adapters/index.js +31 -0
- package/scripts/lib/orchestration/adapters/lm-studio.js +18 -0
- package/scripts/lib/orchestration/adapters/ollama.js +18 -0
- package/scripts/lib/orchestration/adapters/opencode.js +18 -0
- package/scripts/lib/orchestration/adapters/openrouter.js +18 -0
- package/scripts/lib/orchestration/adapters/test-runner.js +25 -0
- package/scripts/lib/orchestration/cli.js +438 -0
- package/scripts/lib/orchestration/execution-manager.js +279 -0
- package/scripts/lib/orchestration/handoff.js +314 -0
- package/scripts/lib/orchestration/index.js +456 -0
- package/scripts/lib/orchestration/inventory.js +47 -0
- package/scripts/lib/orchestration/model-discovery.js +498 -0
- package/scripts/lib/orchestration/model-profiler.js +170 -0
- package/scripts/lib/orchestration/model-profiles.js +252 -0
- package/scripts/lib/orchestration/model-refresh-policy.js +72 -0
- package/scripts/lib/orchestration/proof-writer.js +349 -0
- package/scripts/lib/orchestration/provider-discovery/aider.js +49 -0
- package/scripts/lib/orchestration/provider-discovery/claude-code.js +56 -0
- package/scripts/lib/orchestration/provider-discovery/codex.js +49 -0
- package/scripts/lib/orchestration/provider-discovery/common.js +186 -0
- package/scripts/lib/orchestration/provider-discovery/gemini.js +106 -0
- package/scripts/lib/orchestration/provider-discovery/lm-studio.js +118 -0
- package/scripts/lib/orchestration/provider-discovery/models-dev.js +12 -0
- package/scripts/lib/orchestration/provider-discovery/ollama.js +100 -0
- package/scripts/lib/orchestration/provider-discovery/opencode.js +47 -0
- package/scripts/lib/orchestration/provider-discovery/openrouter.js +44 -0
- package/scripts/lib/orchestration/risk-classifier.js +130 -0
- package/scripts/lib/orchestration/routing-policy.js +486 -0
- package/scripts/lib/orchestration/settings.js +95 -0
- package/scripts/lib/orchestration/state.js +165 -0
- package/scripts/lib/orchestration/verification-manager.js +138 -0
- package/scripts/lib/outcome-evidence-stack.js +1083 -0
- package/scripts/lib/output-profiles.js +146 -0
- package/scripts/lib/package-content-audit.js +368 -0
- package/scripts/lib/package-runtime.js +278 -0
- package/scripts/lib/plan-surface.js +53 -0
- package/scripts/lib/plans.js +2327 -0
- package/scripts/lib/policy-provider.js +27 -0
- package/scripts/lib/prelaunch-activation-readiness.js +409 -0
- package/scripts/lib/prelaunch-evidence-store.js +816 -0
- package/scripts/lib/prelaunch-intelligence.js +869 -0
- package/scripts/lib/pricing-experiment.js +118 -0
- package/scripts/lib/pro-moment-events.js +77 -0
- package/scripts/lib/pro-moment-state.js +227 -0
- package/scripts/lib/pro-moments.js +1216 -0
- package/scripts/lib/product-home-receipt.js +1790 -0
- package/scripts/lib/product-learning-events.js +696 -0
- package/scripts/lib/production-confidence-control-tower.js +1209 -0
- package/scripts/lib/production-confidence.js +1858 -0
- package/scripts/lib/project-profile.js +555 -0
- package/scripts/lib/prompt-compiler-plan.js +94 -0
- package/scripts/lib/prompt-compiler.js +280 -0
- package/scripts/lib/prompt-lint.js +32 -0
- package/scripts/lib/prompt-suggestions.js +52 -0
- package/scripts/lib/proof-canonical.js +398 -0
- package/scripts/lib/proof-drilldown.js +383 -0
- package/scripts/lib/proof-e2e/promise-completion.js +141 -0
- package/scripts/lib/proof-e2e/promise-dashboard-claims.js +135 -0
- package/scripts/lib/proof-e2e/promise-local-proof.js +156 -0
- package/scripts/lib/proof-e2e/promise-provider-neutral.js +136 -0
- package/scripts/lib/proof-e2e/promise-registry.js +219 -0
- package/scripts/lib/proof-e2e/promise-security-trust.js +141 -0
- package/scripts/lib/proof-e2e/promise-skills-risk.js +163 -0
- package/scripts/lib/proof-e2e/promise-token-savings.js +112 -0
- package/scripts/lib/proof-e2e/promise-work-management.js +126 -0
- package/scripts/lib/proof-events.js +342 -0
- package/scripts/lib/proof-history.js +243 -0
- package/scripts/lib/proof-metrics.js +296 -0
- package/scripts/lib/proof-outcome-evidence.js +134 -0
- package/scripts/lib/proof-receipt.js +335 -0
- package/scripts/lib/proof-record.js +461 -0
- package/scripts/lib/proof-savings-report.js +1549 -0
- package/scripts/lib/public-activation-distribution-gate.js +266 -0
- package/scripts/lib/public-cli.js +5631 -0
- package/scripts/lib/public-distribution-truth.js +211 -0
- package/scripts/lib/public-distribution.js +73 -0
- package/scripts/lib/public-install-claim-checker.js +300 -0
- package/scripts/lib/publish-provenance-readiness.js +287 -0
- package/scripts/lib/readiness-delta.js +218 -0
- package/scripts/lib/readiness-evidence-closure.js +196 -0
- package/scripts/lib/reentry-memory-capture.js +241 -0
- package/scripts/lib/reentry-memory-retrieval.js +302 -0
- package/scripts/lib/reentry-memory-status.js +147 -0
- package/scripts/lib/reentry-memory-store.js +183 -0
- package/scripts/lib/reentry-state.js +66 -0
- package/scripts/lib/release-candidate-bundle.js +166 -0
- package/scripts/lib/remediation.js +81 -0
- package/scripts/lib/repo-map.js +391 -0
- package/scripts/lib/run-action-policy.js +104 -0
- package/scripts/lib/run-contract-receipt.js +48 -0
- package/scripts/lib/run-contract.js +288 -0
- package/scripts/lib/run-cost-to-verified-outcome.js +87 -0
- package/scripts/lib/run-improvements-lifecycle.js +330 -0
- package/scripts/lib/run-improvements.js +789 -0
- package/scripts/lib/run-proof-contract.js +116 -0
- package/scripts/lib/run-risk-classifier.js +131 -0
- package/scripts/lib/run-task-classifier.js +216 -0
- package/scripts/lib/runtime-decision-policy.js +387 -0
- package/scripts/lib/safe-path-engine.js +705 -0
- package/scripts/lib/safe-repair.js +877 -0
- package/scripts/lib/safe-run-controller.js +887 -0
- package/scripts/lib/scope-repair-before-approval.js +865 -0
- package/scripts/lib/score.js +262 -0
- package/scripts/lib/seamless-enforcement.js +329 -0
- package/scripts/lib/seamless-outcome.js +689 -0
- package/scripts/lib/seamless-reality-gate.js +5053 -0
- package/scripts/lib/security-confidence/activation-safety.js +78 -0
- package/scripts/lib/security-confidence/adapters/adapter-contract.js +125 -0
- package/scripts/lib/security-confidence/adapters/mock-claude-bughunter-adapter.js +36 -0
- package/scripts/lib/security-confidence/adapters/mock-decepticon-adapter.js +34 -0
- package/scripts/lib/security-confidence/adapters/mock-mcp-scan-adapter.js +35 -0
- package/scripts/lib/security-confidence/adapters/mock-snyk-agent-scan-adapter.js +35 -0
- package/scripts/lib/security-confidence/adapters/mock-tank-adapter.js +34 -0
- package/scripts/lib/security-confidence/adapters/reference-registry.js +63 -0
- package/scripts/lib/security-confidence/auth-rbac-plan.js +39 -0
- package/scripts/lib/security-confidence/component-inventory.js +151 -0
- package/scripts/lib/security-confidence/constants.js +191 -0
- package/scripts/lib/security-confidence/dependency-script-risk.js +95 -0
- package/scripts/lib/security-confidence/evidence-hygiene.js +127 -0
- package/scripts/lib/security-confidence/feature-impact-classifier.js +80 -0
- package/scripts/lib/security-confidence/file-utils.js +161 -0
- package/scripts/lib/security-confidence/finding-triage.js +90 -0
- package/scripts/lib/security-confidence/findings.js +115 -0
- package/scripts/lib/security-confidence/index.js +29 -0
- package/scripts/lib/security-confidence/permission-budget.js +93 -0
- package/scripts/lib/security-confidence/redaction.js +82 -0
- package/scripts/lib/security-confidence/redteam-fixtures.js +53 -0
- package/scripts/lib/security-confidence/reference-adoption.js +229 -0
- package/scripts/lib/security-confidence/reference-taxonomy.js +155 -0
- package/scripts/lib/security-confidence/report-quality.js +99 -0
- package/scripts/lib/security-confidence/report-writer.js +79 -0
- package/scripts/lib/security-confidence/risk-classifier.js +187 -0
- package/scripts/lib/security-confidence/runner.js +179 -0
- package/scripts/lib/security-confidence/schema.js +188 -0
- package/scripts/lib/security-confidence/secret-safety.js +74 -0
- package/scripts/lib/security-confidence/security-capability-router.js +98 -0
- package/scripts/lib/security-confidence/web-security-smoke-plan.js +46 -0
- package/scripts/lib/security-risk-classifier.js +511 -0
- package/scripts/lib/security-scan.js +396 -0
- package/scripts/lib/session-context-optimizer.js +1211 -0
- package/scripts/lib/session-timing.js +322 -0
- package/scripts/lib/skill-hygiene.js +805 -0
- package/scripts/lib/skill-packs.js +161 -0
- package/scripts/lib/skills-operating-layer-v1.js +1023 -0
- package/scripts/lib/skills-operating-layer.js +629 -0
- package/scripts/lib/smallest-safe-plan.js +214 -0
- package/scripts/lib/smart-routing-plan.js +115 -0
- package/scripts/lib/smart-work-routing.js +768 -0
- package/scripts/lib/source-catalog.js +1022 -0
- package/scripts/lib/status-value-summary.js +32 -0
- package/scripts/lib/supply-chain-dependency-guard.js +1333 -0
- package/scripts/lib/supply-chain-guard.js +219 -0
- package/scripts/lib/support-bundle.js +561 -0
- package/scripts/lib/support-redaction.js +66 -0
- package/scripts/lib/task-continuation.js +440 -0
- package/scripts/lib/test-helpers.js +15 -0
- package/scripts/lib/tier.js +38 -0
- package/scripts/lib/token-context-quality-gate.js +370 -0
- package/scripts/lib/token-cost-capture.js +187 -0
- package/scripts/lib/token-cost-evidence.js +862 -0
- package/scripts/lib/token-cost-intelligence.js +358 -0
- package/scripts/lib/token-efficiency-evidence.js +213 -0
- package/scripts/lib/token-efficiency-map.js +110 -0
- package/scripts/lib/token-evidence.js +703 -0
- package/scripts/lib/tokenish.js +17 -0
- package/scripts/lib/tool-output-sandbox.js +559 -0
- package/scripts/lib/trust-audit.js +136 -0
- package/scripts/lib/unified-events.js +396 -0
- package/scripts/lib/upgrade-interruption-recovery.js +407 -0
- package/scripts/lib/usage-ledger.js +201 -0
- package/scripts/lib/value-ledger.js +130 -0
- package/scripts/lib/value-proof-calibration.js +531 -0
- package/scripts/lib/visual-qa.js +231 -0
- package/scripts/lib/voice-alpha.js +29 -0
- package/scripts/lib/webhook-idempotency-guard.js +990 -0
- package/scripts/lib/work-aware-orchestration.js +976 -0
- package/scripts/lib/work-control-receipts.js +577 -0
- package/scripts/lib/work-ledger.js +1123 -0
- package/scripts/lib/work-panel-preview.js +352 -0
- package/scripts/lib/workflow-discipline.js +280 -0
- package/scripts/lib/workflow-intelligence-radar.js +804 -0
- package/scripts/lib/workflow-signals.js +419 -0
- package/scripts/lib/workspace-map.js +281 -0
- package/scripts/lib/workspace-registry.js +1367 -0
- package/scripts/lib/workspace-resolver.js +542 -0
- package/scripts/wuz-doctor.js +315 -0
- package/bin/avorelo.mjs +0 -7
- package/dist/avorelo.mjs +0 -24678
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { checkFixEligibility } = require('./skills/safe-fix-policy');
|
|
6
|
+
|
|
7
|
+
function generateLlmsTxt(productFacts) {
|
|
8
|
+
if (!productFacts) return null;
|
|
9
|
+
const lines = [
|
|
10
|
+
`# ${productFacts.product_name || 'Product'}`,
|
|
11
|
+
'',
|
|
12
|
+
`> ${productFacts.short_description || ''}`,
|
|
13
|
+
'',
|
|
14
|
+
`## What it is`,
|
|
15
|
+
productFacts.what_it_is || '',
|
|
16
|
+
'',
|
|
17
|
+
`## What it is not`,
|
|
18
|
+
...(productFacts.what_it_is_not || []).map(s => `- ${s}`),
|
|
19
|
+
'',
|
|
20
|
+
`## Category`,
|
|
21
|
+
productFacts.category || '',
|
|
22
|
+
'',
|
|
23
|
+
`## Core value`,
|
|
24
|
+
productFacts.core_value || '',
|
|
25
|
+
'',
|
|
26
|
+
`## Plans`,
|
|
27
|
+
productFacts.free_plan ? `- Free: ${productFacts.free_plan.includes || ''}` : '',
|
|
28
|
+
productFacts.pro_plan ? `- Pro: ${productFacts.pro_plan.includes || ''}` : '',
|
|
29
|
+
productFacts.teams_plan ? `- Teams: ${productFacts.teams_plan.includes || ''}` : '',
|
|
30
|
+
'',
|
|
31
|
+
`## Integrations`,
|
|
32
|
+
(productFacts.integrations || []).join(', '),
|
|
33
|
+
'',
|
|
34
|
+
`## Security`,
|
|
35
|
+
productFacts.security_positioning || '',
|
|
36
|
+
].filter(l => l !== undefined);
|
|
37
|
+
return lines.join('\n') + '\n';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function generateHeadersFile() {
|
|
41
|
+
return [
|
|
42
|
+
'/*',
|
|
43
|
+
' X-Content-Type-Options: nosniff',
|
|
44
|
+
' X-Frame-Options: DENY',
|
|
45
|
+
' Referrer-Policy: strict-origin-when-cross-origin',
|
|
46
|
+
'',
|
|
47
|
+
].join('\n');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function executeSafeFixes(findings, context) {
|
|
51
|
+
const applied = [];
|
|
52
|
+
const skipped = [];
|
|
53
|
+
|
|
54
|
+
for (const f of findings) {
|
|
55
|
+
if (!f.autoFixEligible) continue;
|
|
56
|
+
|
|
57
|
+
// llms.txt generation
|
|
58
|
+
if (f.id === 'io-no-llms-txt' && context.publicWebSrc && context.productFacts) {
|
|
59
|
+
const policy = checkFixEligibility('llms-txt');
|
|
60
|
+
if (!policy.allowed) { skipped.push({ ...f, reason: policy.reason }); continue; }
|
|
61
|
+
|
|
62
|
+
const content = generateLlmsTxt(context.productFacts);
|
|
63
|
+
if (content) {
|
|
64
|
+
const target = path.join(context.publicWebSrc, 'llms.txt');
|
|
65
|
+
const before = fs.existsSync(target) ? fs.readFileSync(target, 'utf8') : null;
|
|
66
|
+
fs.writeFileSync(target, content, 'utf8');
|
|
67
|
+
applied.push({
|
|
68
|
+
findingId: f.id,
|
|
69
|
+
type: 'llms-txt',
|
|
70
|
+
file: target,
|
|
71
|
+
before: before ? 'existing file updated' : 'file did not exist',
|
|
72
|
+
after: `Generated ${content.length} bytes from product facts`,
|
|
73
|
+
reversible: true,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Static headers file
|
|
79
|
+
if (f.id === 'io-no-static-headers-config' && context.publicWebSrc) {
|
|
80
|
+
const policy = checkFixEligibility('x-content-type-options');
|
|
81
|
+
if (!policy.allowed) { skipped.push({ ...f, reason: policy.reason }); continue; }
|
|
82
|
+
|
|
83
|
+
const target = path.join(context.publicWebSrc, '_headers');
|
|
84
|
+
if (!fs.existsSync(target)) {
|
|
85
|
+
const content = generateHeadersFile();
|
|
86
|
+
fs.writeFileSync(target, content, 'utf8');
|
|
87
|
+
applied.push({
|
|
88
|
+
findingId: f.id,
|
|
89
|
+
type: 'x-content-type-options',
|
|
90
|
+
file: target,
|
|
91
|
+
before: 'file did not exist',
|
|
92
|
+
after: 'Created _headers with X-Content-Type-Options, X-Frame-Options, Referrer-Policy',
|
|
93
|
+
reversible: true,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return { applied, skipped };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function revertFixes(appliedFixes) {
|
|
103
|
+
const reverted = [];
|
|
104
|
+
for (const fix of appliedFixes) {
|
|
105
|
+
if (fix.reversible && fix.before === 'file did not exist') {
|
|
106
|
+
try {
|
|
107
|
+
fs.unlinkSync(fix.file);
|
|
108
|
+
reverted.push({ file: fix.file, type: fix.type, result: 'deleted' });
|
|
109
|
+
} catch (e) {
|
|
110
|
+
reverted.push({ file: fix.file, type: fix.type, result: `revert failed: ${e.message}` });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return reverted;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
module.exports = { executeSafeFixes, revertFixes, generateLlmsTxt, generateHeadersFile };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { BANNED_PHRASES } = require('./pmm-positioning-guard');
|
|
4
|
+
|
|
5
|
+
function runCategoryGuard(texts) {
|
|
6
|
+
const allText = (Array.isArray(texts) ? texts : [texts]).join('\n');
|
|
7
|
+
const findings = [];
|
|
8
|
+
|
|
9
|
+
for (const phrase of BANNED_PHRASES) {
|
|
10
|
+
const re = new RegExp(phrase.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'gi');
|
|
11
|
+
let match;
|
|
12
|
+
while ((match = re.exec(allText)) !== null) {
|
|
13
|
+
const ctx = allText.slice(Math.max(0, match.index - 80), match.index + match[0].length + 40);
|
|
14
|
+
if (/not an?\s/i.test(ctx) || /\*\*not\*\*/i.test(ctx) || /is not/i.test(ctx) || /avoid/i.test(ctx) || /anti-trigger/i.test(ctx) || /what.it.is.not/i.test(ctx) || /asks about/i.test(ctx) || /not a/i.test(ctx)) continue;
|
|
15
|
+
findings.push({
|
|
16
|
+
id: `cat-boundary-${phrase.replace(/\s+/g, '-')}`,
|
|
17
|
+
category: 'pmm',
|
|
18
|
+
source: 'skill',
|
|
19
|
+
severity: 'blocking',
|
|
20
|
+
confidence: 'measured',
|
|
21
|
+
title: `Category drift: "${match[0]}"`,
|
|
22
|
+
detail: ctx.trim(),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return { pass: findings.length === 0, findings };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = { runCategoryGuard };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const BANNED_PHRASES = [
|
|
4
|
+
'seo optimizer', 'aeo platform', 'geo dashboard',
|
|
5
|
+
'ai search ranking tool', 'marketing analytics suite',
|
|
6
|
+
'unlock full report', 'rank higher', 'boost ai visibility',
|
|
7
|
+
'boost your ai visibility', 'fix your ai seo',
|
|
8
|
+
'website grader',
|
|
9
|
+
];
|
|
10
|
+
|
|
11
|
+
const REQUIRED_CONCEPTS = [
|
|
12
|
+
'ai work control',
|
|
13
|
+
'outside-in',
|
|
14
|
+
'inside',
|
|
15
|
+
'safe fix',
|
|
16
|
+
'proof',
|
|
17
|
+
'no signup',
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
function runPmmGuard(texts) {
|
|
21
|
+
const findings = [];
|
|
22
|
+
const allText = (Array.isArray(texts) ? texts : [texts]).join('\n').toLowerCase();
|
|
23
|
+
|
|
24
|
+
for (const phrase of BANNED_PHRASES) {
|
|
25
|
+
const idx = allText.indexOf(phrase);
|
|
26
|
+
if (idx !== -1) {
|
|
27
|
+
const context = allText.slice(Math.max(0, idx - 80), idx + phrase.length + 40);
|
|
28
|
+
// Allow in "what Avorelo is not" / anti-trigger / negative positioning context
|
|
29
|
+
if (/not an?\s/i.test(context) || /\*\*not\*\*/i.test(context) || /is not/i.test(context) || /anti-trigger/i.test(context) || /what.it.is.not/i.test(context) || /avoid/i.test(context)) continue;
|
|
30
|
+
findings.push({
|
|
31
|
+
id: `pmm-banned-${phrase.replace(/\s+/g, '-')}`,
|
|
32
|
+
category: 'pmm',
|
|
33
|
+
source: 'skill',
|
|
34
|
+
severity: 'blocking',
|
|
35
|
+
confidence: 'measured',
|
|
36
|
+
title: `Banned phrase: "${phrase}"`,
|
|
37
|
+
detail: `Found in: "...${context.trim()}..."`,
|
|
38
|
+
evidence: context.trim(),
|
|
39
|
+
autoFixEligible: false,
|
|
40
|
+
requiresApproval: true,
|
|
41
|
+
suggestedFix: 'Remove or rephrase to avoid category drift.',
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const missingConcepts = REQUIRED_CONCEPTS.filter(c => !allText.includes(c));
|
|
47
|
+
if (missingConcepts.length > 2) {
|
|
48
|
+
findings.push({
|
|
49
|
+
id: 'pmm-missing-concepts',
|
|
50
|
+
category: 'pmm',
|
|
51
|
+
source: 'skill',
|
|
52
|
+
severity: 'advisory',
|
|
53
|
+
confidence: 'estimated',
|
|
54
|
+
title: 'Missing core positioning concepts',
|
|
55
|
+
detail: `Missing: ${missingConcepts.join(', ')}`,
|
|
56
|
+
evidence: missingConcepts.join(', '),
|
|
57
|
+
autoFixEligible: false,
|
|
58
|
+
requiresApproval: false,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
pass: findings.filter(f => f.severity === 'blocking').length === 0,
|
|
64
|
+
riskLevel: findings.length === 0 ? 'low' : findings.some(f => f.severity === 'blocking') ? 'high' : 'medium',
|
|
65
|
+
findings,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
module.exports = { runPmmGuard, BANNED_PHRASES, REQUIRED_CONCEPTS };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const ALLOWED_AUTO = [
|
|
4
|
+
'title', 'meta-description', 'og-metadata', 'twitter-metadata', 'canonical',
|
|
5
|
+
'json-ld', 'llms-txt', 'sitemap-basic', 'robots-basic', 'aria-label', 'internal-docs-link',
|
|
6
|
+
'x-content-type-options',
|
|
7
|
+
];
|
|
8
|
+
|
|
9
|
+
const REQUIRES_APPROVAL = [
|
|
10
|
+
'pricing-claims', 'legal-privacy-terms', 'security-compliance-claims',
|
|
11
|
+
'auth-payment-flows', 'oauth-api-mcp-exposure', 'competitor-comparison',
|
|
12
|
+
'aggressive-csp-session-cookie', 'destructive-file-change',
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
function checkFixEligibility(fixType) {
|
|
16
|
+
if (ALLOWED_AUTO.includes(fixType)) return { allowed: true, requiresApproval: false };
|
|
17
|
+
if (REQUIRES_APPROVAL.includes(fixType)) return { allowed: false, requiresApproval: true, reason: `"${fixType}" requires human approval.` };
|
|
18
|
+
return { allowed: false, requiresApproval: true, reason: `Unknown fix type "${fixType}" requires approval.` };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function runSafeFixPolicy(plannedFixes) {
|
|
22
|
+
const approved = [];
|
|
23
|
+
const needsAttention = [];
|
|
24
|
+
for (const fix of plannedFixes) {
|
|
25
|
+
const result = checkFixEligibility(fix.type);
|
|
26
|
+
if (result.allowed) {
|
|
27
|
+
approved.push({ ...fix, policyResult: 'approved' });
|
|
28
|
+
} else {
|
|
29
|
+
needsAttention.push({ ...fix, policyResult: 'requires_approval', reason: result.reason });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return { approved, needsAttention };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = { checkFixEligibility, runSafeFixPolicy, ALLOWED_AUTO, REQUIRES_APPROVAL };
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// ── External User Simulation ──────────────────────────────────────────────────
|
|
4
|
+
// Contract: avorelo.externalUserSimulation.v1
|
|
5
|
+
// Simulates an external user's first experience across 10 key scenarios.
|
|
6
|
+
// Does NOT modify user config, apply hooks, patch MCP, or run destructive commands.
|
|
7
|
+
|
|
8
|
+
const fs = require("fs");
|
|
9
|
+
const path = require("path");
|
|
10
|
+
const { nowIso } = require("./fsx");
|
|
11
|
+
const { appendProductLearningEvent } = require("./product-learning-events");
|
|
12
|
+
|
|
13
|
+
const CONTRACT = "avorelo.externalUserSimulation.v1";
|
|
14
|
+
const SCHEMA_VERSION = 1;
|
|
15
|
+
const SIM_DIR_REL = ".claude/cco/orchestration/full-readiness";
|
|
16
|
+
const ARTIFACT_REL = SIM_DIR_REL + "/latest-external-user-simulation.json";
|
|
17
|
+
|
|
18
|
+
function safeReadJson(absPath) {
|
|
19
|
+
try {
|
|
20
|
+
if (!fs.existsSync(absPath)) return null;
|
|
21
|
+
return JSON.parse(fs.readFileSync(absPath, "utf8").replace(/^/, ""));
|
|
22
|
+
} catch { return null; }
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function buildExternalUserScenarios(cwd, options) {
|
|
26
|
+
options = options || {};
|
|
27
|
+
return [
|
|
28
|
+
{ id: "scenario_1_see_install_prompt", title: "Fresh user sees install-ai prompt", description: "A new user runs `avorelo install-ai --prompt` and sees the one-prompt AI install experience.", expectedBehavior: "Compact prompt text appears. Approval boundaries are visible. No auto-apply.", safetyConstraints: ["no_config_modification", "no_auto_apply"] },
|
|
29
|
+
{ id: "scenario_2_run_ai_install", title: "User runs AI install prompt in simulated order", description: "User follows the AI install prompt steps: install-ai, prelaunch-readiness, first-value-check.", expectedBehavior: "Each step returns a compact JSON result. Journey steps complete in order.", safetyConstraints: ["no_destructive_commands", "no_prod_deploy"] },
|
|
30
|
+
{ id: "scenario_3_hooks_not_applied", title: "User has hooks not applied", description: "User runs `avorelo hooks doctor` and sees hooks are not yet applied.", expectedBehavior: "Doctor shows hooks_not_applied warning. safeNextAction points to `hooks apply --yes`.", safetyConstraints: ["no_auto_hook_apply", "requires_explicit_approval"] },
|
|
31
|
+
{ id: "scenario_4_mcp_governance_warning", title: "User sees MCP governance warning", description: "User runs `avorelo mcp doctor` and sees MCP servers inventoried with risk scores.", expectedBehavior: "Inventory shows servers and risk levels. Policy is preview-only — no auto-patch.", safetyConstraints: ["no_mcp_config_patch", "preview_only"] },
|
|
32
|
+
{ id: "scenario_5_token_cost_not_available", title: "User sees token/cost not_available", description: "User runs `avorelo token-cost` before completing any tasks.", expectedBehavior: "Status is not_available. Caveats explain estimates vs exact. No exact savings claimed.", safetyConstraints: ["no_exact_savings_claim", "caveats_required"] },
|
|
33
|
+
{ id: "scenario_6_support_bundle", title: "User needs support bundle", description: "User runs `avorelo support-bundle --json` to get a redacted support bundle.", expectedBehavior: "Bundle is redacted. No raw prompts, code, secrets, or PII. Safe to share.", safetyConstraints: ["redacted", "no_raw_prompts", "no_raw_code", "no_secrets"] },
|
|
34
|
+
{ id: "scenario_7_missing_proof_outcome", title: "User hits missing proof/outcome", description: "User runs `avorelo open` before completing any task — no proof available.", expectedBehavior: "Compact message: no proof available. safeNextAction: run a task first.", safetyConstraints: ["no_false_proof_claim", "safeNextAction_required"] },
|
|
35
|
+
{ id: "scenario_8_known_limitations", title: "User reads known limitations", description: "User runs `avorelo known-limitations --json` and reads the limitations register.", expectedBehavior: "Limitations are honest, categorized, and include mitigations. No hidden limitations.", safetyConstraints: ["honest_limitations", "no_hidden_limitations"] },
|
|
36
|
+
{ id: "scenario_9_see_next_action", title: "User sees next action", description: "User runs `avorelo full-readiness --json` and sees a clear safeNextAction.", expectedBehavior: "safeNextAction is specific and actionable. No vague or generic next step.", safetyConstraints: ["specific_next_action", "actionable"] },
|
|
37
|
+
{ id: "scenario_10_blocked_action_safe_next", title: "User gets blocked action with safeNextAction", description: "User attempts an action that is blocked. safeNextAction guides recovery.", expectedBehavior: "Blocked action shows safeNextAction. User is not left without guidance.", safetyConstraints: ["every_blocker_has_safeNextAction", "no_silent_failure"] },
|
|
38
|
+
];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function evaluateExternalUserScenario(cwd, scenario, options) {
|
|
42
|
+
options = options || {};
|
|
43
|
+
function read(rel) { return safeReadJson(path.join(cwd, rel)); }
|
|
44
|
+
var status = "pass";
|
|
45
|
+
var finding = null;
|
|
46
|
+
var evidence = null;
|
|
47
|
+
|
|
48
|
+
switch (scenario.id) {
|
|
49
|
+
case "scenario_1_see_install_prompt": {
|
|
50
|
+
var ip = read(".claude/cco/orchestration/ai-install/latest-prompt.json");
|
|
51
|
+
if (!ip) { status = "warn"; finding = "AI install prompt not generated. Run: node bin/avorelo install-ai --json"; }
|
|
52
|
+
else if (!ip.requiresApprovalFor || ip.requiresApprovalFor.length === 0) { status = "warn"; finding = "Approval boundaries not explicitly listed in install prompt."; }
|
|
53
|
+
else { finding = "Install prompt present with approval boundaries."; evidence = { artifactPath: ".claude/cco/orchestration/ai-install/latest-prompt.json" }; }
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
case "scenario_2_run_ai_install": {
|
|
57
|
+
var ip2 = read(".claude/cco/orchestration/ai-install/latest-prompt.json");
|
|
58
|
+
var pr = read(".claude/cco/orchestration/prelaunch-readiness/latest-activation-readiness.json");
|
|
59
|
+
var steps = [ip2, pr].filter(Boolean).length;
|
|
60
|
+
if (steps < 2) { status = "warn"; finding = "Only " + steps + "/2 journey steps have receipts."; }
|
|
61
|
+
else finding = "Core install journey steps have receipts.";
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
case "scenario_3_hooks_not_applied": {
|
|
65
|
+
var hd = read(".claude/cco/orchestration/hook-doctor/latest-doctor.json");
|
|
66
|
+
if (!hd) { status = "warn"; finding = "Hooks doctor not run. Run: node bin/avorelo hooks doctor --json"; }
|
|
67
|
+
else {
|
|
68
|
+
var hasApprovalCheck = (hd.checks || []).some(function(c) { return c.id === "no_global_config_modified"; });
|
|
69
|
+
if (!hasApprovalCheck) { status = "warn"; finding = "Hooks doctor missing explicit approval boundary check."; }
|
|
70
|
+
else finding = "Hooks doctor present. Approval required before hooks apply.";
|
|
71
|
+
}
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
case "scenario_4_mcp_governance_warning": {
|
|
75
|
+
var mp = read(".claude/cco/orchestration/mcp-tool-governance/latest-policy.json");
|
|
76
|
+
if (!mp) { status = "warn"; finding = "MCP governance not run. Run: node bin/avorelo mcp doctor --json"; }
|
|
77
|
+
else if (!mp.note || (Array.isArray(mp.note) ? !mp.note.join(" ").includes("preview") : !mp.note.includes("preview"))) { status = "warn"; finding = "MCP policy does not explicitly state preview-only mode."; }
|
|
78
|
+
else finding = "MCP governance present and preview-only note confirmed.";
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
case "scenario_5_token_cost_not_available": {
|
|
82
|
+
var tc = read(".claude/cco/orchestration/prelaunch-intelligence/latest-token-cost-intelligence.json");
|
|
83
|
+
if (!tc) { status = "warn"; finding = "Token/cost intelligence not run. Run: node bin/avorelo token-cost --json"; }
|
|
84
|
+
else if (tc.noExactSavingsClaim !== true) { status = "blocked"; finding = "Token cost intelligence does not have noExactSavingsClaim=true."; }
|
|
85
|
+
else finding = "Token cost status: " + (tc.status || tc.evidenceLevel) + ". Caveats present.";
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
case "scenario_6_support_bundle": {
|
|
89
|
+
var sb = read(".claude/cco/support/latest-support-bundle.json");
|
|
90
|
+
if (!sb) { status = "warn"; finding = "Support bundle not generated. Run: node bin/avorelo support-bundle --json"; }
|
|
91
|
+
else if (sb.redacted !== true) { status = "blocked"; finding = "Support bundle is not marked redacted — safety violation."; }
|
|
92
|
+
else finding = "Support bundle present and redacted.";
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
case "scenario_7_missing_proof_outcome": {
|
|
96
|
+
var vs = read(".claude/cco/orchestration/seamless-outcome/latest-value-summary.json");
|
|
97
|
+
finding = vs ? "Proof/value summary present from prior task." : "No proof available (expected). CLI shows clear message: run a task first.";
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
case "scenario_8_known_limitations": {
|
|
101
|
+
var kl = read(".claude/cco/orchestration/full-readiness/latest-known-limitations.json");
|
|
102
|
+
if (!kl) { status = "warn"; finding = "Known limitations register not yet built. Run: node bin/avorelo known-limitations --json"; }
|
|
103
|
+
else if (!kl.limitations || kl.limitations.length === 0) { status = "warn"; finding = "Known limitations register is empty — limitations must be documented."; }
|
|
104
|
+
else {
|
|
105
|
+
var allMit = kl.limitations.every(function(l) { return l.mitigation && l.mitigation.length > 0; });
|
|
106
|
+
if (!allMit) { status = "warn"; finding = "Some limitations are missing mitigation documentation."; }
|
|
107
|
+
else finding = "Known limitations: " + kl.limitations.length + " documented with mitigations.";
|
|
108
|
+
}
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
case "scenario_9_see_next_action": {
|
|
112
|
+
var gate = read(".claude/cco/orchestration/full-readiness/latest-gate.json");
|
|
113
|
+
if (!gate) { status = "warn"; finding = "Full readiness gate not yet run. Run: node bin/avorelo full-readiness --json"; }
|
|
114
|
+
else if (!gate.safeNextAction || gate.safeNextAction.length < 10) { status = "warn"; finding = "safeNextAction is missing or too vague."; }
|
|
115
|
+
else finding = "safeNextAction present: \"" + gate.safeNextAction.slice(0, 60) + "...\"";
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
case "scenario_10_blocked_action_safe_next": {
|
|
119
|
+
var gate2 = read(".claude/cco/orchestration/full-readiness/latest-gate.json");
|
|
120
|
+
if (!gate2) { status = "warn"; finding = "Full readiness gate not run — cannot verify blocked action handling."; }
|
|
121
|
+
else {
|
|
122
|
+
var allHaveSN = (gate2.blockers || []).every(function(b) { return b.safeNextAction && b.safeNextAction.length > 0; });
|
|
123
|
+
if (!allHaveSN && (gate2.blockers || []).length > 0) { status = "blocked"; finding = "Some blockers are missing safeNextAction."; }
|
|
124
|
+
else finding = gate2.blockers && gate2.blockers.length > 0 ? "All " + gate2.blockers.length + " blockers have safeNextAction." : "No blockers — safeNextAction pattern not needed.";
|
|
125
|
+
}
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
default: status = "warn"; finding = "Unknown scenario: " + scenario.id;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return Object.assign({}, scenario, { result: status, finding: finding, evidence: evidence || null, safetyConstraintsVerified: scenario.safetyConstraints, configModified: false, hooksApplied: false, mcpPatched: false, destructiveCommandRun: false });
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function runExternalUserSimulation(cwd, options) {
|
|
135
|
+
options = options || {};
|
|
136
|
+
var scenarios = buildExternalUserScenarios(cwd, options);
|
|
137
|
+
var evaluated = scenarios.map(function(s) { return evaluateExternalUserScenario(cwd, s, options); });
|
|
138
|
+
var passed = evaluated.filter(function(s) { return s.result === "pass"; }).length;
|
|
139
|
+
var warned = evaluated.filter(function(s) { return s.result === "warn"; }).length;
|
|
140
|
+
var blocked = evaluated.filter(function(s) { return s.result === "blocked"; }).length;
|
|
141
|
+
var overallStatus = blocked > 0 ? "blocked" : warned > 0 ? "warn" : "pass";
|
|
142
|
+
var simulation = { contract: CONTRACT, schemaVersion: SCHEMA_VERSION, createdAt: nowIso(), status: overallStatus, totalScenarios: scenarios.length, passed: passed, warned: warned, blocked: blocked, scenarios: evaluated, safetyGuarantees: { configModified: false, hooksApplied: false, mcpPatched: false, destructiveCommandRun: false, publicLaunchClaimed: false }, redacted: true };
|
|
143
|
+
try { appendProductLearningEvent(cwd, { eventName: "external_user_simulation_run", category: "full_readiness", status: overallStatus, passed: passed, warned: warned, blocked: blocked }); } catch (e) {}
|
|
144
|
+
return simulation;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function writeExternalUserSimulation(cwd, simulation) {
|
|
148
|
+
var dir = path.join(cwd, SIM_DIR_REL);
|
|
149
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
150
|
+
fs.writeFileSync(path.join(cwd, ARTIFACT_REL), JSON.stringify(simulation, null, 2));
|
|
151
|
+
return simulation;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function formatExternalUserSimulationText(simulation, options) {
|
|
155
|
+
options = options || {};
|
|
156
|
+
var lines = [];
|
|
157
|
+
lines.push("External user simulation: " + simulation.status + " (" + simulation.passed + "/" + simulation.totalScenarios + " pass)");
|
|
158
|
+
if (simulation.blocked > 0 || simulation.warned > 0) {
|
|
159
|
+
lines.push(""); lines.push("Issues:");
|
|
160
|
+
simulation.scenarios.filter(function(s) { return s.result !== "pass"; }).forEach(function(s) { lines.push(" [" + s.result + "] " + s.title); lines.push(" " + s.finding); });
|
|
161
|
+
}
|
|
162
|
+
lines.push(""); lines.push("Safety: no config modified, no hooks applied, no MCP patched.");
|
|
163
|
+
return lines.join("\n");
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
module.exports = { CONTRACT, SCHEMA_VERSION, ARTIFACT_REL, runExternalUserSimulation, buildExternalUserScenarios, evaluateExternalUserScenario, writeExternalUserSimulation, formatExternalUserSimulationText };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
|
|
6
|
+
const { nowIso } = require("./fsx");
|
|
7
|
+
|
|
8
|
+
const CONTRACT = "avorelo.failureRecoveryReadiness.v1";
|
|
9
|
+
const SCHEMA_VERSION = 1;
|
|
10
|
+
const RECEIPT_REL = ".claude/cco/orchestration/failure-recovery/latest-recovery.json";
|
|
11
|
+
|
|
12
|
+
function safeReadJson(absPath) {
|
|
13
|
+
try {
|
|
14
|
+
if (!fs.existsSync(absPath)) return null;
|
|
15
|
+
return JSON.parse(fs.readFileSync(absPath, "utf8").replace(/^\uFEFF/, ""));
|
|
16
|
+
} catch {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function buildFailureRecoveryReadiness(cwd) {
|
|
22
|
+
const receipt = safeReadJson(path.join(cwd, RECEIPT_REL));
|
|
23
|
+
const launchHardening = safeReadJson(path.join(cwd, ".claude/cco/orchestration/launch-hardening/latest-gate.json"));
|
|
24
|
+
const supportBundle = safeReadJson(path.join(cwd, ".claude/cco/support/latest-support-bundle.json"));
|
|
25
|
+
const knownLimitations = safeReadJson(path.join(cwd, ".claude/cco/orchestration/full-readiness/latest-known-limitations.json"));
|
|
26
|
+
|
|
27
|
+
let moduleAvailable = false;
|
|
28
|
+
try {
|
|
29
|
+
const mod = require("./failure-recovery");
|
|
30
|
+
moduleAvailable = typeof mod.buildRecoveryPlan === "function" || typeof mod.buildFailureRecoveryReceipt === "function";
|
|
31
|
+
} catch {
|
|
32
|
+
moduleAvailable = false;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const missingEvidence = [];
|
|
36
|
+
const safeNextActions = [];
|
|
37
|
+
|
|
38
|
+
if (!moduleAvailable) {
|
|
39
|
+
missingEvidence.push("Failure recovery module is not loadable.");
|
|
40
|
+
safeNextActions.push("Inspect: scripts/lib/failure-recovery.js");
|
|
41
|
+
}
|
|
42
|
+
if (!launchHardening) {
|
|
43
|
+
missingEvidence.push("Launch hardening gate artifact is missing.");
|
|
44
|
+
safeNextActions.push("Run: node bin/avorelo launch-hardening --json");
|
|
45
|
+
}
|
|
46
|
+
if (!supportBundle || supportBundle.redacted !== true) {
|
|
47
|
+
missingEvidence.push("Redacted support bundle is missing.");
|
|
48
|
+
safeNextActions.push("Run: node bin/avorelo support-bundle --json");
|
|
49
|
+
}
|
|
50
|
+
if (!knownLimitations) {
|
|
51
|
+
missingEvidence.push("Known limitations register is missing.");
|
|
52
|
+
safeNextActions.push("Run: node bin/avorelo full-readiness --json");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const status = missingEvidence.length === 0 ? "pass" : "warn";
|
|
56
|
+
const safeNextAction = safeNextActions[0] || "Run: node bin/avorelo full-readiness --json";
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
contract: CONTRACT,
|
|
60
|
+
schemaVersion: SCHEMA_VERSION,
|
|
61
|
+
createdAt: nowIso(),
|
|
62
|
+
status,
|
|
63
|
+
receiptAvailable: receipt !== null,
|
|
64
|
+
moduleAvailable,
|
|
65
|
+
launchHardeningAvailable: launchHardening !== null,
|
|
66
|
+
supportBundleAvailable: supportBundle?.redacted === true,
|
|
67
|
+
knownLimitationsAvailable: knownLimitations !== null,
|
|
68
|
+
artifactPath: RECEIPT_REL,
|
|
69
|
+
missingEvidence,
|
|
70
|
+
safeNextActions: safeNextActions.length ? safeNextActions : [safeNextAction],
|
|
71
|
+
safeNextAction,
|
|
72
|
+
redacted: true,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
module.exports = {
|
|
77
|
+
CONTRACT,
|
|
78
|
+
SCHEMA_VERSION,
|
|
79
|
+
RECEIPT_REL,
|
|
80
|
+
buildFailureRecoveryReadiness,
|
|
81
|
+
};
|