@event4u/agent-config 14.10.0 → 14.11.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 +335 -0
- package/README.md +1 -1
- package/dist/agent-src/commands/design.md +88 -0
- package/dist/agent-src/commands/project/analyze.md +47 -0
- package/dist/agent-src/commands/review/changes.md +67 -6
- package/dist/agent-src/commands/roadmap/create.md +49 -0
- package/dist/agent-src/commands/roadmap/next.md +27 -11
- package/dist/agent-src/commands/roadmap/process-full.md +14 -0
- package/dist/agent-src/commands/video/from-script.md +60 -3
- package/dist/agent-src/commands/video/stitch.md +14 -0
- package/dist/agent-src/contexts/communication/rules-auto/guidelines-mechanics.md +1 -0
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +154 -2
- package/dist/agent-src/rules/active-remediation.md +3 -3
- package/dist/agent-src/rules/code-provenance.md +2 -2
- package/dist/agent-src/rules/context-hygiene.md +13 -33
- package/dist/agent-src/rules/council-availability.md +2 -2
- package/dist/agent-src/rules/decision-revisit-gate.md +3 -1
- package/dist/agent-src/rules/design-fidelity.md +18 -0
- package/dist/agent-src/rules/design-review-after-ui-write.md +2 -2
- package/dist/agent-src/rules/evaluator-independence.md +56 -44
- package/dist/agent-src/rules/fix-what-you-see.md +9 -1
- package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +1 -1
- package/dist/agent-src/rules/minimal-safe-diff.md +14 -20
- package/dist/agent-src/rules/missing-skill-recovery.md +13 -1
- package/dist/agent-src/rules/playbook-precedence.md +105 -0
- package/dist/agent-src/rules/recurring-criticism.md +3 -1
- package/dist/agent-src/rules/roadmap-progress-sync.md +14 -13
- package/dist/agent-src/rules/scale-discipline.md +24 -0
- package/dist/agent-src/rules/security-sensitive-stop.md +2 -2
- package/dist/agent-src/rules/settings-ask-protocol.md +2 -2
- package/dist/agent-src/rules/ui-audit-gate.md +27 -15
- package/dist/agent-src/rules/untrusted-input-defense.md +2 -2
- package/dist/agent-src/skills/accessibility-auditor/SKILL.md +19 -0
- package/dist/agent-src/skills/adr-create/SKILL.md +7 -0
- package/dist/agent-src/skills/agents-md-thin-root/SKILL.md +33 -0
- package/dist/agent-src/skills/ai-council/references/advanced-modes.md +17 -3
- package/dist/agent-src/skills/ai-council/references/output-and-synthesis.md +31 -0
- package/dist/agent-src/skills/ai-council/references/procedure.md +19 -0
- package/dist/agent-src/skills/alerting-doctrine/SKILL.md +225 -0
- package/dist/agent-src/skills/alerting-doctrine/evals/triggers.json +17 -0
- package/dist/agent-src/skills/authz-review/SKILL.md +0 -1
- package/dist/agent-src/skills/blast-radius-analyzer/SKILL.md +32 -0
- package/dist/agent-src/skills/brand/SKILL.md +3 -0
- package/dist/agent-src/skills/brand-asset-generation/SKILL.md +3 -0
- package/dist/agent-src/skills/brand-audit/SKILL.md +3 -0
- package/dist/agent-src/skills/brand-identity/SKILL.md +3 -0
- package/dist/agent-src/skills/brand-strategy/SKILL.md +3 -0
- package/dist/agent-src/skills/brand-to-tokens/SKILL.md +3 -0
- package/dist/agent-src/skills/check-refs/SKILL.md +3 -0
- package/dist/agent-src/skills/code-review/SKILL.md +11 -0
- package/dist/agent-src/skills/command-routing/SKILL.md +6 -0
- package/dist/agent-src/skills/condense-memory/SKILL.md +3 -0
- package/dist/agent-src/skills/context-authoring/SKILL.md +1 -1
- package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +3 -0
- package/dist/agent-src/skills/copilot-agents-optimization/SKILL.md +10 -0
- package/dist/agent-src/skills/corpus-grounding/SKILL.md +3 -0
- package/dist/agent-src/skills/design-intelligence/SKILL.md +3 -0
- package/dist/agent-src/skills/design-intelligence/data/landing.csv +36 -35
- package/dist/agent-src/skills/design-intelligence/data/stacks/threejs.csv +1 -0
- package/dist/agent-src/skills/design-review/SKILL.md +79 -1
- package/dist/agent-src/skills/design-review/references/verification-automation.md +41 -0
- package/dist/agent-src/skills/design-system-capture/SKILL.md +35 -40
- package/dist/agent-src/skills/design-system-capture/references/import-procedure.md +50 -0
- package/dist/agent-src/skills/design-tokens/SKILL.md +3 -0
- package/dist/agent-src/skills/design-variations/SKILL.md +3 -0
- package/dist/agent-src/skills/developer-like-execution/SKILL.md +3 -0
- package/dist/agent-src/skills/estimate-ticket/SKILL.md +3 -0
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +20 -3
- package/dist/agent-src/skills/fe-design/SKILL.md +74 -41
- package/dist/agent-src/skills/fe-design/evals/triggers.json +65 -53
- package/dist/agent-src/skills/fe-design/references/craft-floor.md +52 -0
- package/dist/agent-src/skills/fe-design/references/source-led-port.md +36 -0
- package/dist/agent-src/skills/file-editor/SKILL.md +5 -0
- package/dist/agent-src/skills/finishing-a-development-branch/SKILL.md +2 -2
- package/dist/agent-src/skills/git-workflow/SKILL.md +3 -0
- package/dist/agent-src/skills/html-deck/SKILL.md +3 -0
- package/dist/agent-src/skills/iconography/SKILL.md +3 -0
- package/dist/agent-src/skills/image-editing/SKILL.md +3 -0
- package/dist/agent-src/skills/image-generation/SKILL.md +3 -0
- package/dist/agent-src/skills/image-provider-routing/SKILL.md +3 -0
- package/dist/agent-src/skills/incident-commander/SKILL.md +10 -0
- package/dist/agent-src/skills/js-library-packaging/SKILL.md +173 -0
- package/dist/agent-src/skills/js-library-packaging/evals/triggers.json +17 -0
- package/dist/agent-src/skills/js-library-packaging/scripts/check_package_surface.ts +270 -0
- package/dist/agent-src/skills/laravel-migration/SKILL.md +3 -0
- package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +3 -0
- package/dist/agent-src/skills/lint-skills/SKILL.md +3 -0
- package/dist/agent-src/skills/llm-provider-knowledge/SKILL.md +3 -0
- package/dist/agent-src/skills/logging-monitoring/SKILL.md +234 -51
- package/dist/agent-src/skills/logo-generation/SKILL.md +3 -0
- package/dist/agent-src/skills/md-language-check/SKILL.md +3 -0
- package/dist/agent-src/skills/monorepo-workspace/SKILL.md +149 -0
- package/dist/agent-src/skills/monorepo-workspace/evals/triggers.json +17 -0
- package/dist/agent-src/skills/motion-choreographer/SKILL.md +6 -0
- package/dist/agent-src/skills/multi-tenancy/SKILL.md +4 -0
- package/dist/agent-src/skills/operational-readiness/SKILL.md +184 -0
- package/dist/agent-src/skills/operational-readiness/evals/triggers.json +17 -0
- package/dist/agent-src/skills/override-management/SKILL.md +3 -0
- package/dist/agent-src/skills/persona-improvement/SKILL.md +3 -0
- package/dist/agent-src/skills/pest-testing/SKILL.md +3 -0
- package/dist/agent-src/skills/playbook-authoring/SKILL.md +162 -0
- package/dist/agent-src/skills/playwright-testing/SKILL.md +3 -0
- package/dist/agent-src/skills/privacy-review/SKILL.md +3 -0
- package/dist/agent-src/skills/prompt-engineering-image/SKILL.md +3 -0
- package/dist/agent-src/skills/quality-tools/SKILL.md +5 -0
- package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +52 -21
- package/dist/agent-src/skills/readme-reviewer/SKILL.md +3 -0
- package/dist/agent-src/skills/readme-writing/SKILL.md +3 -0
- package/dist/agent-src/skills/readme-writing-package/SKILL.md +3 -0
- package/dist/agent-src/skills/receiving-code-review/SKILL.md +2 -2
- package/dist/agent-src/skills/refine-prompt/SKILL.md +3 -0
- package/dist/agent-src/skills/refine-ticket/SKILL.md +3 -0
- package/dist/agent-src/skills/requesting-code-review/SKILL.md +2 -2
- package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +23 -41
- package/dist/agent-src/skills/roadmap-writing/references/follow-up-roadmap-shape.md +47 -0
- package/dist/agent-src/skills/rtk-output-filtering/SKILL.md +22 -6
- package/dist/agent-src/skills/runway-cognition/SKILL.md +3 -0
- package/dist/agent-src/skills/scene-expander/scene-blueprint.schema.yaml +26 -0
- package/dist/agent-src/skills/secrets-management/SKILL.md +4 -0
- package/dist/agent-src/skills/server-hardening/SKILL.md +159 -0
- package/dist/agent-src/skills/server-hardening/evals/triggers.json +17 -0
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +3 -0
- package/dist/agent-src/skills/skill-management/SKILL.md +3 -0
- package/dist/agent-src/skills/skill-reviewer/SKILL.md +3 -0
- package/dist/agent-src/skills/skill-writing/SKILL.md +6 -0
- package/dist/agent-src/skills/spreadsheet-authoring/SKILL.md +3 -0
- package/dist/agent-src/skills/storybook-workshop/SKILL.md +194 -0
- package/dist/agent-src/skills/storybook-workshop/evals/triggers.json +17 -0
- package/dist/agent-src/skills/storybook-workshop/scripts/story_contrast_floor.ts +134 -0
- package/dist/agent-src/skills/subagent-orchestration/SKILL.md +1 -1
- package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +25 -0
- package/dist/agent-src/skills/supply-chain-intake/SKILL.md +12 -0
- package/dist/agent-src/skills/systematic-debugging/SKILL.md +1 -1
- package/dist/agent-src/skills/terraform/SKILL.md +3 -0
- package/dist/agent-src/skills/test-driven-development/SKILL.md +1 -1
- package/dist/agent-src/skills/threat-modeling/SKILL.md +0 -3
- package/dist/agent-src/skills/token-optimizer/SKILL.md +3 -0
- package/dist/agent-src/skills/typography-system/SKILL.md +3 -0
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +9 -1
- package/dist/agent-src/skills/upstream-contribute/SKILL.md +3 -0
- package/dist/agent-src/skills/validate-feature-fit/SKILL.md +3 -0
- package/dist/agent-src/skills/verify-completion-evidence/SKILL.md +2 -2
- package/dist/agent-src/skills/wireframe/SKILL.md +3 -0
- package/dist/agent-src/skills/wireframe/references/story-beat-ledger.schema.json +115 -0
- package/dist/agent-src/skills/workspace-link/SKILL.md +131 -0
- package/dist/agent-src/skills/workspace-link/evals/triggers.json +17 -0
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/playbook.md +75 -0
- package/dist/agent-src/templates/roadmaps.md +37 -0
- package/dist/agent-src/templates/scripts/check_playbook_invokes.ts +231 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +24 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +2 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/review.ts +216 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +159 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +73 -4
- package/dist/agent-src/templates/scripts/work_engine/stack/detect.ts +325 -40
- package/dist/cli/commands/uiAudit.js +221 -0
- package/dist/cli/commands/uiAudit.js.map +1 -0
- package/dist/cli/commands/uiRender.js +206 -0
- package/dist/cli/commands/uiRender.js.map +1 -0
- package/dist/cli/main.js +22 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/mcp/content.js +64 -1
- package/dist/cli/mcp/content.js.map +1 -1
- package/dist/cli/mcp/dispatch.js +175 -10
- package/dist/cli/mcp/dispatch.js.map +1 -1
- package/dist/cli/registry.js +3 -0
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli-delegate/{chunk-H4VIVD4C.js → chunk-236PNQZK.js} +413 -391
- package/dist/cli-delegate/{chunk-G23AT6GD.js → chunk-DMSZHXZS.js} +57 -1
- package/dist/cli-delegate/{chunk-77GR3VD4.js → chunk-FF7WAFMR.js} +58 -3
- package/dist/cli-delegate/{chunk-PLSG6UL5.js → chunk-K4FFODTS.js} +341 -204
- package/dist/cli-delegate/{chunk-YM4GZDJG.js → chunk-L43NCYPB.js} +5 -0
- package/dist/cli-delegate/{chunk-B2ERU2VA.js → chunk-WOKWX5PL.js} +1 -1
- package/dist/cli-delegate/cmd_brand_status.js +8 -6
- package/dist/cli-delegate/cmd_conformance.js +3 -3
- package/dist/cli-delegate/cmd_doctor.js +3 -3
- package/dist/cli-delegate/cmd_export.js +4 -4
- package/dist/cli-delegate/cmd_handoff.js +1 -1
- package/dist/cli-delegate/cmd_preflight.js +2 -2
- package/dist/cli-delegate/cmd_prune.js +4 -4
- package/dist/cli-delegate/cmd_session_recycle.js +70 -9
- package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +4 -4
- package/dist/cli-delegate/cmd_uninstall.js +4 -4
- package/dist/cli-delegate/cmd_validate.js +4 -4
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +359 -124
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +4 -4
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +18 -8
- package/dist/discovery/trust-report.md +3 -3
- package/dist/discovery/workspaces.json +16 -6
- package/dist/hooks/dispatch.js +2337 -1436
- package/dist/install/install.mjs +795 -708
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +1685 -1250
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/lean_projection_mode.js +40 -0
- package/dist/scripts/_lib/lean_projection_mode.js.map +1 -0
- package/dist/scripts/_lib/scoped_projection.js +84 -0
- package/dist/scripts/_lib/scoped_projection.js.map +1 -1
- package/dist/scripts/_lib/ui_surface.js +89 -0
- package/dist/scripts/_lib/ui_surface.js.map +1 -0
- package/dist/scripts/condense.js +6 -10
- package/dist/scripts/condense.js.map +1 -1
- package/dist/scripts/project_thin_rules.js +40 -2
- package/dist/scripts/project_thin_rules.js.map +1 -1
- package/dist/server/schemas/settings.js +3 -0
- package/dist/server/schemas/settings.js.map +1 -1
- package/dist/shared/skillRanking.js +159 -0
- package/dist/shared/skillRanking.js.map +1 -0
- package/docs/contracts/provider-lifecycle.md +47 -18
- package/docs/contracts/settings-classes.md +14 -4
- package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +49 -0
- package/docs/guidelines/agent-infra/evaluator-independence-mechanics.md +92 -0
- package/docs/guidelines/agent-infra/minimal-safe-diff-mechanics.md +45 -1
- package/docs/guidelines/agent-infra/roadmap-deferred-resolution-provenance.md +54 -0
- package/docs/guidelines/design-antipatterns.md +4 -2
- package/docs/guidelines/design-asset-discipline.md +38 -0
- package/docs/guidelines/design-fidelity-mechanics.md +45 -29
- package/docs/guidelines/design-handover-extraction.md +35 -5
- package/docs/guidelines/design-modes.md +41 -1
- package/docs/guidelines/monorepo-antipatterns.md +141 -0
- package/llms.txt +50 -39
- package/package.json +1 -1
- package/src/agent-src/templates/scripts/check_playbook_invokes.ts +231 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +24 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +2 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/review.ts +216 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +159 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +73 -4
- package/src/agent-src/templates/scripts/work_engine/stack/detect.ts +325 -40
- package/src/config/agent-settings.template.yml +28 -0
- package/src/config/assurance-capability-registry.json +223 -0
- package/src/config/assurance-threshold-budget.json +65 -0
- package/src/config/ci-local-parity.yml +14 -0
- package/src/config/discovery/unassigned-artefacts.yml +2 -0
- package/src/config/dispatch-economy-metrics.json +4 -2
- package/src/config/evaluator-budgets.json +14 -14
- package/src/config/gate-coverage.yml +207 -8
- package/src/config/gate-violation-baselines.json +76 -72
- package/src/config/hook-latency-budget.json +1 -0
- package/src/config/hook-token-budget.json +137 -125
- package/src/config/pack-size-budget.json +4 -2
- package/src/config/quorum-attendance-budget.json +12 -4
- package/src/config/rule-activation-census.json +7 -3
- package/src/config/rule-enforcement-baseline.json +0 -1
- package/src/config/rule-stub-ceilings.json +112 -91
- package/src/scripts/_cli/cmd_doctor.ts +15 -16
- package/src/scripts/_cli/doctor_install_mode.ts +49 -0
- package/src/scripts/_cli/doctor_overrides.ts +154 -0
- package/src/scripts/_dispatch.bash +17 -0
- package/src/scripts/_lib/as_of.ts +412 -0
- package/src/scripts/_lib/exec_evidence.ts +7 -0
- package/src/scripts/_lib/hook_settings.ts +33 -0
- package/src/scripts/_lib/host_listing_model.ts +192 -0
- package/src/scripts/_lib/lean_projection_mode.ts +44 -0
- package/src/scripts/_lib/mcp_bridge.ts +199 -0
- package/src/scripts/_lib/review_independence.ts +62 -10
- package/src/scripts/_lib/rule_injection.ts +239 -0
- package/src/scripts/_lib/run_checkpoint.ts +54 -1
- package/src/scripts/_lib/scoped_projection.ts +96 -0
- package/src/scripts/_lib/session_register.ts +44 -2
- package/src/scripts/_lib/skill_catalogue.ts +38 -2
- package/src/scripts/_lib/transcript_reads.ts +207 -0
- package/src/scripts/_lib/ui_authority.test.ts +251 -0
- package/src/scripts/_lib/ui_authority.ts +343 -0
- package/src/scripts/ai-video/adapters/fal.sh +8 -3
- package/src/scripts/ai-video/adapters/gemini-veo.sh +10 -0
- package/src/scripts/ai-video/adapters/higgsfield.sh +10 -2
- package/src/scripts/ai-video/adapters/kling.sh +10 -0
- package/src/scripts/ai-video/adapters/sora.sh +10 -0
- package/src/scripts/ai-video/lib/calibrate-cost.sh +145 -0
- package/src/scripts/ai-video/lib/model-capabilities/README.md +53 -7
- package/src/scripts/ai-video/lib/model-capabilities/comfyui.json +15 -3
- package/src/scripts/ai-video/lib/model-capabilities/fal.json +36 -6
- package/src/scripts/ai-video/lib/model-capabilities/gemini-veo.json +23 -0
- package/src/scripts/ai-video/lib/model-capabilities/higgsfield.json +23 -0
- package/src/scripts/ai-video/lib/model-capabilities/kling.json +23 -0
- package/src/scripts/ai-video/lib/model-capabilities/musetalk.json +8 -2
- package/src/scripts/ai-video/lib/model-capabilities/replicate.json +36 -6
- package/src/scripts/ai-video/lib/model-capabilities/sora.json +45 -0
- package/src/scripts/ai-video/lib/model-capabilities/syncso.json +8 -2
- package/src/scripts/ai-video/lib/parse-blueprint.sh +52 -5
- package/src/scripts/ai-video/lib/resume-scan.sh +92 -3
- package/src/scripts/ai-video/lib/seam-plan.sh +212 -0
- package/src/scripts/ai-video/smoke-trace.sh +450 -2
- package/src/scripts/ai-video/stitch.sh +191 -10
- package/src/scripts/ai-video/test-pipeline.sh +84 -6
- package/src/scripts/ai_council/cli_agency_bounds.ts +139 -0
- package/src/scripts/ai_council/cli_least_agency_canary.ts +347 -0
- package/src/scripts/ai_council/clients.ts +3 -2
- package/src/scripts/ai_council/consensus.ts +63 -6
- package/src/scripts/ai_council/events_log.ts +46 -1
- package/src/scripts/ai_council/orchestrator.ts +103 -108
- package/src/scripts/ai_council/orchestrator_results.ts +166 -0
- package/src/scripts/ai_council/prompts.ts +12 -5
- package/src/scripts/ai_council/quorum.ts +82 -1
- package/src/scripts/ai_council/quorum_wiring.ts +82 -5
- package/src/scripts/ai_council/stance_tally.ts +22 -0
- package/src/scripts/bench_hook_latency.ts +62 -0
- package/src/scripts/build_proof.ts +12 -1
- package/src/scripts/capture_skill_catalogue.ts +21 -0
- package/src/scripts/check_always_budget.ts +2 -1
- package/src/scripts/check_augmentignore.ts +2 -1
- package/src/scripts/check_beta_review_markers.ts +2 -1
- package/src/scripts/check_composite_arming.ts +364 -0
- package/src/scripts/check_corpus_staleness.ts +2 -1
- package/src/scripts/check_council_pin_staleness.ts +3 -1
- package/src/scripts/check_enforcement_coverage.ts +116 -3
- package/src/scripts/check_enforcement_denominator.ts +365 -0
- package/src/scripts/check_gate_coverage.ts +2 -1
- package/src/scripts/check_hook_bundle_freshness.ts +13 -1
- package/src/scripts/check_knowledge_cards.ts +2 -1
- package/src/scripts/check_knowledge_pages.ts +3 -2
- package/src/scripts/check_memory.ts +2 -1
- package/src/scripts/check_no_automerge_key.ts +287 -0
- package/src/scripts/check_pack_conformance_fixture.ts +565 -0
- package/src/scripts/check_proposal.ts +2 -1
- package/src/scripts/check_reach_staleness.ts +2 -1
- package/src/scripts/check_release_adjacent_health.ts +2 -1
- package/src/scripts/check_release_pr_shape.ts +5 -0
- package/src/scripts/check_review_schema.ts +34 -1
- package/src/scripts/check_roadmap_trackable.ts +48 -3
- package/src/scripts/check_source_size_budget.ts +2 -1
- package/src/scripts/check_standing_payload_delta.ts +505 -0
- package/src/scripts/check_trigger_evals.ts +2 -1
- package/src/scripts/classify_change_risk.ts +281 -0
- package/src/scripts/compute_skill_tiers.ts +186 -0
- package/src/scripts/condense.ts +8 -13
- package/src/scripts/council_attendance_metrics.ts +183 -0
- package/src/scripts/council_cli.ts +10 -8
- package/src/scripts/council_parse_rate.ts +116 -0
- package/src/scripts/derive_playbooks.ts +406 -0
- package/src/scripts/design_slop_rules.test.ts +7 -0
- package/src/scripts/design_slop_rules.ts +56 -2
- package/src/scripts/dispatch_r2_reviewer.ts +16 -0
- package/src/scripts/frontend_corpus_hash.ts +116 -0
- package/src/scripts/grade_target_readiness.ts +478 -0
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +97 -16
- package/src/scripts/hooks/concern_registry.ts +4 -0
- package/src/scripts/hooks/design_pass_hook.ts +356 -0
- package/src/scripts/hooks/rtk_wrap_hook.ts +30 -7
- package/src/scripts/hooks/rule_inject_hook.ts +318 -0
- package/src/scripts/hot_context_hook.ts +74 -7
- package/src/scripts/install.ts +40 -89
- package/src/scripts/lint_adapter_tier.ts +663 -0
- package/src/scripts/lint_archived_skills.ts +93 -0
- package/src/scripts/lint_budget_ownership.ts +2 -1
- package/src/scripts/lint_deterministic_time.ts +470 -0
- package/src/scripts/lint_framework_leakage.ts +5 -0
- package/src/scripts/lint_handoffs.ts +525 -1
- package/src/scripts/lint_judge_prompt_expectation.ts +155 -0
- package/src/scripts/lint_marketplace.ts +88 -0
- package/src/scripts/lint_media_policy_linkage.ts +140 -1
- package/src/scripts/lint_one_off_age.ts +6 -1
- package/src/scripts/lint_override_kernel_guard.ts +87 -5
- package/src/scripts/lint_roadmap_complexity.ts +56 -0
- package/src/scripts/lint_rule_enforcement_declaration.ts +24 -7
- package/src/scripts/lint_rule_norm_pin.ts +321 -0
- package/src/scripts/lint_spawn_payload.ts +42 -5
- package/src/scripts/lint_symptom_intake.ts +2 -1
- package/src/scripts/mcp_parity_smoke.ts +30 -4
- package/src/scripts/mcp_render.ts +66 -1
- package/src/scripts/mcp_tool_fingerprint.ts +241 -0
- package/src/scripts/measure_risk_class_drift.ts +140 -0
- package/src/scripts/measure_skill_ranker_baseline.ts +212 -0
- package/src/scripts/media/lib/adapter-common.sh +211 -1
- package/src/scripts/media/lib/adapter-contract.md +74 -6
- package/src/scripts/model_rule_injection.ts +907 -0
- package/src/scripts/project_thin_rules.ts +45 -2
- package/src/scripts/release.ts +66 -860
- package/src/scripts/release_drill.ts +59 -3
- package/src/scripts/release_env.ts +298 -0
- package/src/scripts/release_publication.ts +720 -0
- package/src/scripts/roadmap_context.ts +778 -0
- package/src/scripts/schemas/fidelity-measurement-sheet.schema.json +169 -0
- package/src/scripts/schemas/rule.schema.json +24 -2
- package/src/scripts/schemas/skill.schema.json +39 -0
- package/src/scripts/schemas/ui-authority.schema.json +114 -0
- package/src/scripts/session_register_hook.ts +29 -3
- package/src/scripts/sessions_cli.ts +67 -3
- package/src/scripts/skill_tools/score_skill_relevance.ts +36 -53
- package/src/scripts/token_sink_report.ts +239 -0
- package/src/scripts/trigger_coverage.ts +122 -3
- package/src/scripts/update_counts.ts +7 -3
- package/src/scripts/validate_frontmatter.ts +66 -0
- package/src/server/schemas/settings.ts +5 -0
- package/src/shared/skillRanking.ts +183 -0
|
@@ -19,9 +19,33 @@
|
|
|
19
19
|
#
|
|
20
20
|
# Usage:
|
|
21
21
|
# bash src/scripts/ai-video/smoke-trace.sh --provider <id> [--live] [--out <dir>]
|
|
22
|
+
# bash src/scripts/ai-video/smoke-trace.sh index [--traces <dir>] [--out <file>]
|
|
23
|
+
# bash src/scripts/ai-video/smoke-trace.sh assumed <adapter>
|
|
22
24
|
#
|
|
23
25
|
# Exit: 0 = trace captured (dry-run plumbing OK, or live success),
|
|
24
26
|
# non-zero = adapter/harness error (recorded in the trace + stderr).
|
|
27
|
+
#
|
|
28
|
+
# Subcommand `index` — the reviewer-reachable projection of the local traces.
|
|
29
|
+
# The raw traces are deliberately local-only (commit d7f5d5d3c, 2026-06-10):
|
|
30
|
+
# they carry request bodies, provider response bodies and signed URLs, and
|
|
31
|
+
# `git ls-files` over the trace path returns 0. That decision stands. What it
|
|
32
|
+
# left broken is that a reviewer holding a clone could not check an adapter's
|
|
33
|
+
# `# Lifecycle: stable` claim at all. `index` fixes exactly that, and nothing
|
|
34
|
+
# else: it emits a FIVE-FIELD row per trace — provider, trace_id,
|
|
35
|
+
# captured_at, model, sha256 — and copies no trace content whatsoever. The
|
|
36
|
+
# allowlist is the security property, not a formatting choice: exclusion by
|
|
37
|
+
# construction, never a redaction pass over a body that might hide a secret
|
|
38
|
+
# the scrub did not know about (`domain-safety-pii` § Surface 2 states the
|
|
39
|
+
# preference; this is that preference applied).
|
|
40
|
+
#
|
|
41
|
+
# `model` is the FILESYSTEM-SAFE SLUG the capture path wrote into the
|
|
42
|
+
# filename (`/` → `_`), never the provider's model id reversed back out —
|
|
43
|
+
# that transformation is lossy and guessing its inverse would be a fabricated
|
|
44
|
+
# field. Consumers match by applying the same forward substitution.
|
|
45
|
+
#
|
|
46
|
+
# An absent trace directory is a REFUSAL, not an empty index: a zero-row
|
|
47
|
+
# index is indistinguishable from "no evidence exists", and writing one would
|
|
48
|
+
# turn a missing input into a published claim.
|
|
25
49
|
set -euo pipefail
|
|
26
50
|
|
|
27
51
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
|
@@ -35,10 +59,409 @@ ADAPTER_DIRS=(
|
|
|
35
59
|
# shellcheck source=/dev/null
|
|
36
60
|
. "${ROOT}/src/scripts/media/lib/adapter-common.sh"
|
|
37
61
|
|
|
62
|
+
# --- Subcommands -------------------------------------------------------------
|
|
63
|
+
# Dispatched before the flag parser so the capture path below is unchanged for
|
|
64
|
+
# every caller that does not name a subcommand.
|
|
65
|
+
|
|
66
|
+
_st_sha256() {
|
|
67
|
+
if command -v shasum >/dev/null 2>&1; then
|
|
68
|
+
shasum -a 256 "$1" | cut -d' ' -f1
|
|
69
|
+
elif command -v sha256sum >/dev/null 2>&1; then
|
|
70
|
+
sha256sum "$1" | cut -d' ' -f1
|
|
71
|
+
else
|
|
72
|
+
echo "smoke-trace: need shasum or sha256sum" >&2; exit 3
|
|
73
|
+
fi
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
# Recover the model slug from a trace filename, given the provider.
|
|
77
|
+
# Layout written by the capture path above:
|
|
78
|
+
# <provider>[-<model_slug>]-<mode>-<TS>.json mode = live | dry-run
|
|
79
|
+
# Strip from the right (TS, then mode), then the provider prefix; whatever is
|
|
80
|
+
# left is the slug, and an empty remainder means the trace named no model.
|
|
81
|
+
_st_model_slug() {
|
|
82
|
+
local stem="$1" provider="$2" rest
|
|
83
|
+
rest="$(printf '%s' "${stem}" | sed -E 's/-[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}-[0-9]{2}-[0-9]{2}Z$//')"
|
|
84
|
+
rest="$(printf '%s' "${rest}" | sed -E 's/-(live|dry-run)$//')"
|
|
85
|
+
case "${rest}" in
|
|
86
|
+
"${provider}") printf '' ;;
|
|
87
|
+
"${provider}-"*) printf '%s' "${rest#"${provider}-"}" ;;
|
|
88
|
+
*) printf '' ;;
|
|
89
|
+
esac
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
_st_index() {
|
|
93
|
+
local traces_dir="${ROOT}/agents/reference/ai-video/smoke-traces"
|
|
94
|
+
local out_file="${ROOT}/agents/evidence/ai-video/trace-index.json"
|
|
95
|
+
while [ $# -gt 0 ]; do
|
|
96
|
+
case "$1" in
|
|
97
|
+
--traces) traces_dir="${2:-}"; shift 2 ;;
|
|
98
|
+
--out) out_file="${2:-}"; shift 2 ;;
|
|
99
|
+
*) echo "smoke-trace index: unknown arg '$1'" >&2; exit 2 ;;
|
|
100
|
+
esac
|
|
101
|
+
done
|
|
102
|
+
command -v jq >/dev/null 2>&1 || { echo "smoke-trace: jq required" >&2; exit 3; }
|
|
103
|
+
[ -d "${traces_dir}" ] || {
|
|
104
|
+
echo "smoke-trace index: trace directory not found: ${traces_dir}" >&2
|
|
105
|
+
echo "smoke-trace index: refusing to write an empty index — a zero-row index reads as 'no evidence exists', which is a different claim from 'the traces are not on this disk'." >&2
|
|
106
|
+
exit 7
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
local rows="[]" f stem provider captured slug model_json sha
|
|
110
|
+
for f in "${traces_dir}"/*.json; do
|
|
111
|
+
[ -f "${f}" ] || continue
|
|
112
|
+
stem="$(basename "${f}" .json)"
|
|
113
|
+
provider="$(jq -r '.provider // empty' "${f}" 2>/dev/null || true)"
|
|
114
|
+
captured="$(jq -r '.captured_utc // empty' "${f}" 2>/dev/null || true)"
|
|
115
|
+
if [ -z "${provider}" ] || [ -z "${captured}" ]; then
|
|
116
|
+
echo "smoke-trace index: skipping ${stem} (no .provider/.captured_utc — not a trace)" >&2
|
|
117
|
+
continue
|
|
118
|
+
fi
|
|
119
|
+
slug="$(_st_model_slug "${stem}" "${provider}")"
|
|
120
|
+
if [ -n "${slug}" ]; then
|
|
121
|
+
model_json="$(jq -nc --arg m "${slug}" '$m')"
|
|
122
|
+
else
|
|
123
|
+
model_json="null"
|
|
124
|
+
fi
|
|
125
|
+
sha="$(_st_sha256 "${f}")"
|
|
126
|
+
rows="$(printf '%s' "${rows}" | jq -c \
|
|
127
|
+
--arg p "${provider}" --arg t "${stem}" --arg c "${captured}" \
|
|
128
|
+
--argjson m "${model_json}" --arg s "${sha}" \
|
|
129
|
+
'. + [{provider:$p, trace_id:$t, captured_at:$c, model:$m, sha256:$s}]')"
|
|
130
|
+
done
|
|
131
|
+
|
|
132
|
+
mkdir -p "$(dirname "${out_file}")"
|
|
133
|
+
# Sorted by trace_id so a regeneration is byte-identical and a diff is real.
|
|
134
|
+
printf '%s' "${rows}" | jq --sort-keys 'sort_by(.trace_id)' > "${out_file}"
|
|
135
|
+
printf 'smoke-trace index: %s rows -> %s\n' \
|
|
136
|
+
"$(jq 'length' "${out_file}")" "${out_file#"${ROOT}/"}" >&2
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
# `assumed` — every ASSUMED-tagged field in an adapter, with its line. A field
|
|
140
|
+
# stays ASSUMED until a live trace confirms it; this makes the count auditable
|
|
141
|
+
# instead of a number somebody has to re-grep by hand.
|
|
142
|
+
#
|
|
143
|
+
# `--all` reports `<domain>\t<adapter>\t<count>` and a total. `--domain
|
|
144
|
+
# <ai-video|ai-image>` narrows it, and the narrowing is not cosmetic: the
|
|
145
|
+
# ai-image adapters carry one ASSUMED tag each and belong to a different
|
|
146
|
+
# adapter population than the video set, so a single undifferentiated total
|
|
147
|
+
# answers no question anybody actually asks. (Measured 2026-08-23: ai-video 21
|
|
148
|
+
# across 7 adapters, ai-image 4 across 4, 25 in all.)
|
|
149
|
+
_st_assumed() {
|
|
150
|
+
local target="${1:-}" want_domain="" d f found="" domain
|
|
151
|
+
shift || true
|
|
152
|
+
while [ $# -gt 0 ]; do
|
|
153
|
+
case "$1" in
|
|
154
|
+
--domain) want_domain="${2:-}"; shift 2 ;;
|
|
155
|
+
*) echo "smoke-trace assumed: unknown arg '$1'" >&2; exit 2 ;;
|
|
156
|
+
esac
|
|
157
|
+
done
|
|
158
|
+
[ -n "${target}" ] || { echo "usage: smoke-trace.sh assumed <adapter|--all> [--domain <id>]" >&2; exit 2; }
|
|
159
|
+
if [ "${target}" = "--all" ]; then
|
|
160
|
+
local total=0 n
|
|
161
|
+
for d in "${ADAPTER_DIRS[@]}"; do
|
|
162
|
+
[ -d "${d}" ] || continue
|
|
163
|
+
domain="$(basename "$(dirname "${d}")")"
|
|
164
|
+
[ -z "${want_domain}" ] || [ "${want_domain}" = "${domain}" ] || continue
|
|
165
|
+
for f in "${d}"/*.sh; do
|
|
166
|
+
[ -f "${f}" ] || continue
|
|
167
|
+
n="$(grep -c 'ASSUMED' "${f}" 2>/dev/null || true)"
|
|
168
|
+
[ -n "${n}" ] || n=0
|
|
169
|
+
[ "${n}" -gt 0 ] || continue
|
|
170
|
+
printf '%s\t%s\t%s\n' "${domain}" "$(basename "${f}" .sh)" "${n}"
|
|
171
|
+
total=$((total + n))
|
|
172
|
+
done
|
|
173
|
+
done
|
|
174
|
+
printf 'total\t%s\n' "${total}"
|
|
175
|
+
return 0
|
|
176
|
+
fi
|
|
177
|
+
for d in "${ADAPTER_DIRS[@]}"; do
|
|
178
|
+
[ -f "${d}/${target}.sh" ] && { found="${d}/${target}.sh"; break; }
|
|
179
|
+
done
|
|
180
|
+
[ -n "${found}" ] || { echo "smoke-trace assumed: no adapter for '${target}'" >&2; exit 2; }
|
|
181
|
+
grep -n 'ASSUMED' "${found}" || true
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
# --- Image / video similarity primitives ------------------------------------
|
|
185
|
+
# ffmpeg's psnr and ssim filters, parsed to one number on stdout. Split out so
|
|
186
|
+
# the threshold logic is testable on two PNGs without any provider call.
|
|
187
|
+
#
|
|
188
|
+
# `inf` is a REAL answer and is printed as `inf`: two byte-identical frames have
|
|
189
|
+
# no error to measure. Mapping it to a large finite number would make an exact
|
|
190
|
+
# match indistinguishable from a very good one, and every caller here wants the
|
|
191
|
+
# distinction.
|
|
192
|
+
|
|
193
|
+
_st_need_ffmpeg() {
|
|
194
|
+
command -v ffmpeg >/dev/null 2>&1 || { echo "smoke-trace: ffmpeg required for this subcommand" >&2; exit 3; }
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
# _st_psnr <ref> <cmp> -> average PSNR in dB, or `inf`
|
|
198
|
+
_st_psnr() {
|
|
199
|
+
local ref="$1" cmp="$2" out
|
|
200
|
+
[ -r "${ref}" ] || { echo "smoke-trace psnr: cannot read ${ref}" >&2; exit 7; }
|
|
201
|
+
[ -r "${cmp}" ] || { echo "smoke-trace psnr: cannot read ${cmp}" >&2; exit 7; }
|
|
202
|
+
out="$(ffmpeg -hide_banner -nostdin -i "${ref}" -i "${cmp}" -lavfi psnr -f null - 2>&1 \
|
|
203
|
+
| sed -nE 's/.*PSNR .*average:([0-9.]+|inf).*/\1/p' | tail -1)"
|
|
204
|
+
[ -n "${out}" ] || { echo "smoke-trace psnr: ffmpeg produced no PSNR line (mismatched dimensions?)" >&2; exit 8; }
|
|
205
|
+
printf '%s' "${out}"
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
# _st_ssim <ref> <cmp> -> All-channel SSIM in 0..1, or `inf` never (SSIM is bounded)
|
|
209
|
+
_st_ssim() {
|
|
210
|
+
local ref="$1" cmp="$2" out
|
|
211
|
+
[ -r "${ref}" ] || { echo "smoke-trace ssim: cannot read ${ref}" >&2; exit 7; }
|
|
212
|
+
[ -r "${cmp}" ] || { echo "smoke-trace ssim: cannot read ${cmp}" >&2; exit 7; }
|
|
213
|
+
out="$(ffmpeg -hide_banner -nostdin -i "${ref}" -i "${cmp}" -lavfi ssim -f null - 2>&1 \
|
|
214
|
+
| sed -nE 's/.*SSIM .*All:([0-9.]+).*/\1/p' | tail -1)"
|
|
215
|
+
[ -n "${out}" ] || { echo "smoke-trace ssim: ffmpeg produced no SSIM line (mismatched dimensions?)" >&2; exit 8; }
|
|
216
|
+
printf '%s' "${out}"
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
# Numeric comparison that treats `inf` as above every threshold.
|
|
220
|
+
_st_ge() {
|
|
221
|
+
local value="$1" threshold="$2"
|
|
222
|
+
[ "${value}" = "inf" ] && return 0
|
|
223
|
+
node -e 'process.exit(Number(process.argv[1]) >= Number(process.argv[2]) ? 0 : 1)' "${value}" "${threshold}"
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
# The frame-0 identity threshold. 30 dB is the roadmap's stated number and is a
|
|
227
|
+
# STATED DEFAULT, not a measured optimum: it asks "is frame 0 the input still,
|
|
228
|
+
# modulo codec noise", which is a different and much easier question than seam
|
|
229
|
+
# quality — so the "PSNR is the wrong metric for seams" caveat does not transfer
|
|
230
|
+
# here. Revisit-if a model passes at 30 dB while a human says frame 0 is a
|
|
231
|
+
# different image, or fails at 30 dB while a human says it is the same one.
|
|
232
|
+
ST_FRAME0_PSNR_MIN="${AIV_FRAME0_PSNR_MIN:-30}"
|
|
233
|
+
|
|
234
|
+
# psnr / ssim / frame0-verdict — the testable primitives.
|
|
235
|
+
_st_metric() {
|
|
236
|
+
local kind="$1"; shift
|
|
237
|
+
_st_need_ffmpeg
|
|
238
|
+
case "${kind}" in
|
|
239
|
+
psnr) _st_psnr "$@"; printf '\n' ;;
|
|
240
|
+
ssim) _st_ssim "$@"; printf '\n' ;;
|
|
241
|
+
frame0)
|
|
242
|
+
local v; v="$(_st_psnr "$@")"
|
|
243
|
+
if _st_ge "${v}" "${ST_FRAME0_PSNR_MIN}"; then
|
|
244
|
+
printf '{"psnr_frame0":"%s","threshold":%s,"start_frame":true}\n' "${v}" "${ST_FRAME0_PSNR_MIN}"
|
|
245
|
+
else
|
|
246
|
+
printf '{"psnr_frame0":"%s","threshold":%s,"start_frame":false}\n' "${v}" "${ST_FRAME0_PSNR_MIN}"
|
|
247
|
+
fi
|
|
248
|
+
;;
|
|
249
|
+
*) echo "smoke-trace: unknown metric '${kind}'" >&2; exit 2 ;;
|
|
250
|
+
esac
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
# `seam-score <a.mp4> <b.mp4>` — the diagnostic Phase 4 measures with (4.2).
|
|
254
|
+
# The LAST frame of a and the FIRST frame of b are the boundary pair a viewer
|
|
255
|
+
# actually sees across a cut, so those are the two frames scored. Both metrics
|
|
256
|
+
# are emitted because the pre-registered question is which of them (if either)
|
|
257
|
+
# tracks human judgement — picking one here would answer the question the
|
|
258
|
+
# falsifier exists to ask.
|
|
259
|
+
_st_seam_score() {
|
|
260
|
+
local a="${1:-}" b="${2:-}" work last first
|
|
261
|
+
[ -n "${a}" ] && [ -n "${b}" ] || { echo "usage: smoke-trace.sh seam-score <a.mp4> <b.mp4>" >&2; exit 2; }
|
|
262
|
+
_st_need_ffmpeg
|
|
263
|
+
[ -r "${a}" ] || { echo "smoke-trace seam-score: cannot read ${a}" >&2; exit 7; }
|
|
264
|
+
[ -r "${b}" ] || { echo "smoke-trace seam-score: cannot read ${b}" >&2; exit 7; }
|
|
265
|
+
work="$(mktemp -d -t aiv-seam-XXXXXX)"
|
|
266
|
+
trap 'rm -rf "${work}"' RETURN
|
|
267
|
+
last="${work}/last.png"
|
|
268
|
+
first="${work}/first.png"
|
|
269
|
+
# -sseof seeks from the end; 0.15 s back lands inside the final GOP on every
|
|
270
|
+
# frame rate this pipeline emits, and -frames:v 1 takes the first frame after
|
|
271
|
+
# the seek rather than a decoded-but-discarded one.
|
|
272
|
+
ffmpeg -hide_banner -loglevel error -nostdin -y -sseof -0.15 -i "${a}" -frames:v 1 -update 1 "${last}" \
|
|
273
|
+
|| { echo "smoke-trace seam-score: could not extract the last frame of ${a}" >&2; exit 8; }
|
|
274
|
+
ffmpeg -hide_banner -loglevel error -nostdin -y -i "${b}" -frames:v 1 -update 1 "${first}" \
|
|
275
|
+
|| { echo "smoke-trace seam-score: could not extract the first frame of ${b}" >&2; exit 8; }
|
|
276
|
+
printf '{"a":"%s","b":"%s","psnr":"%s","ssim":"%s","note":"diagnostic only — no threshold is a gate until the falsifier decides one (agents/evidence/analysis/seam-score-falsifier.md)"}\n' \
|
|
277
|
+
"${a}" "${b}" "$(_st_psnr "${last}" "${first}")" "$(_st_ssim "${last}" "${first}")"
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
# `probe-frame-lock <adapter> <model>` — does this model actually accept a start
|
|
281
|
+
# frame, and does the rendered clip's frame 0 come back as that frame?
|
|
282
|
+
#
|
|
283
|
+
# COSTS MONEY. Guarded by the same AIV_DRYRUN default as every other live path:
|
|
284
|
+
# without an explicit AIV_DRYRUN=false it prints the plan and the estimate and
|
|
285
|
+
# exits 0 without submitting. The end-frame side deliberately records NO
|
|
286
|
+
# pass/fail number: whether a clip ENDS on a given composition is a judgement
|
|
287
|
+
# about composition, not an identity check, and a dB figure there would be a
|
|
288
|
+
# fabricated verdict wearing a measurement's clothes — it stores the extracted
|
|
289
|
+
# end frame beside the target for a human instead.
|
|
290
|
+
_st_probe_frame_lock() {
|
|
291
|
+
local adapter_id="${1:-}" model="${2:-}" still="" end_still="" out_dir=""
|
|
292
|
+
shift 2 2>/dev/null || true
|
|
293
|
+
while [ $# -gt 0 ]; do
|
|
294
|
+
case "$1" in
|
|
295
|
+
--still) still="${2:-}"; shift 2 ;;
|
|
296
|
+
--end-still) end_still="${2:-}"; shift 2 ;;
|
|
297
|
+
--out) out_dir="${2:-}"; shift 2 ;;
|
|
298
|
+
*) echo "smoke-trace probe-frame-lock: unknown arg '$1'" >&2; exit 2 ;;
|
|
299
|
+
esac
|
|
300
|
+
done
|
|
301
|
+
[ -n "${adapter_id}" ] && [ -n "${model}" ] \
|
|
302
|
+
|| { echo "usage: smoke-trace.sh probe-frame-lock <adapter> <model> [--still <png>] [--end-still <png>] [--out <dir>]" >&2; exit 2; }
|
|
303
|
+
|
|
304
|
+
local adapter=""
|
|
305
|
+
for d in "${ADAPTER_DIRS[@]}"; do
|
|
306
|
+
[ -f "${d}/${adapter_id}.sh" ] && { adapter="${d}/${adapter_id}.sh"; break; }
|
|
307
|
+
done
|
|
308
|
+
[ -n "${adapter}" ] || { echo "smoke-trace probe-frame-lock: no adapter for '${adapter_id}'" >&2; exit 2; }
|
|
309
|
+
|
|
310
|
+
local manifest="${ROOT}/src/scripts/ai-video/lib/model-capabilities/${adapter_id}.json"
|
|
311
|
+
local min_dur cost aspect
|
|
312
|
+
min_dur="$(jq -r --arg m "${model}" '.models[$m].min_duration // empty' "${manifest}" 2>/dev/null || true)"
|
|
313
|
+
cost="$(jq -r --arg m "${model}" '.models[$m].cost_per_second_usd // empty' "${manifest}" 2>/dev/null || true)"
|
|
314
|
+
aspect="$(jq -r --arg m "${model}" '.models[$m].aspect[0] // "16:9"' "${manifest}" 2>/dev/null || printf '16:9')"
|
|
315
|
+
[ -n "${min_dur}" ] || min_dur=4
|
|
316
|
+
local est="unknown"
|
|
317
|
+
if [ -n "${cost}" ] && [ "${cost}" != "null" ]; then
|
|
318
|
+
est="$(node -e 'process.stdout.write(String(Number(process.argv[1]) * Number(process.argv[2])))' "${cost}" "${min_dur}")"
|
|
319
|
+
fi
|
|
320
|
+
|
|
321
|
+
local dryrun="${AIV_DRYRUN:-true}"
|
|
322
|
+
case "${dryrun}" in false|FALSE|0|no|NO) dryrun=0 ;; *) dryrun=1 ;; esac
|
|
323
|
+
|
|
324
|
+
if [ "${dryrun}" -eq 1 ]; then
|
|
325
|
+
jq -nc --arg a "${adapter_id}" --arg m "${model}" --arg d "${min_dur}" \
|
|
326
|
+
--arg asp "${aspect}" --arg est "${est}" '{
|
|
327
|
+
dry_run: true, adapter: $a, model: $m, duration_s: ($d|tonumber), aspect: $asp,
|
|
328
|
+
estimated_usd: $est,
|
|
329
|
+
plan: "render one clip from the fixture still at the cheapest duration, extract frame 0, PSNR against the still",
|
|
330
|
+
note: "NO submit performed. Set AIV_DRYRUN=false to spend. The end-frame side records the extracted end frame for a human and no pass/fail number."
|
|
331
|
+
}'
|
|
332
|
+
return 0
|
|
333
|
+
fi
|
|
334
|
+
|
|
335
|
+
# Argument validation BEFORE the ffmpeg probe, deliberately. A missing
|
|
336
|
+
# `--still` is a usage error: the command is malformed on every machine, and
|
|
337
|
+
# the message should not depend on which tools happen to be installed. A
|
|
338
|
+
# missing ffmpeg is an environment error for a call that would never have been
|
|
339
|
+
# made anyway. Ordering them the other way made this path report
|
|
340
|
+
# "ffmpeg required" on a CI runner with no ffmpeg, hiding the real mistake.
|
|
341
|
+
[ -n "${still}" ] || { echo "smoke-trace probe-frame-lock: --still <png> is required for a live probe" >&2; exit 2; }
|
|
342
|
+
[ -r "${still}" ] || { echo "smoke-trace probe-frame-lock: cannot read --still ${still}" >&2; exit 7; }
|
|
343
|
+
_st_need_ffmpeg
|
|
344
|
+
out_dir="${out_dir:-${ROOT}/agents/reference/ai-video/smoke-traces/frame-lock}"
|
|
345
|
+
mkdir -p "${out_dir}"
|
|
346
|
+
local stamp clip frame0
|
|
347
|
+
stamp="$(date -u +%Y-%m-%dT%H-%M-%SZ)"
|
|
348
|
+
clip="${out_dir}/${adapter_id}-$(printf '%s' "${model}" | tr '/' '_')-${stamp}.mp4"
|
|
349
|
+
frame0="${clip%.mp4}-frame0.png"
|
|
350
|
+
|
|
351
|
+
local stdin_json
|
|
352
|
+
stdin_json="$(jq -nc --arg m "${model}" --arg ref "${still}" --arg asp "${aspect}" --argjson dur "${min_dur}" '{
|
|
353
|
+
prompt: {style:"frame-lock probe", subject:"the supplied still, continuing",
|
|
354
|
+
environment:"as in the still", action:"minimal motion", camera:"locked",
|
|
355
|
+
lens:"as in the still", lighting:"as in the still", mood:"neutral"},
|
|
356
|
+
duration: $dur, aspect: $asp, seed: 1, model_id: $m, ref_images: [$ref]
|
|
357
|
+
} + (if $end != "" then {end_image: $end} else {} end)' --arg end "${end_still}")"
|
|
358
|
+
|
|
359
|
+
AIV_DRYRUN=false AIV_OUT="${clip}" printf '%s' "${stdin_json}" | bash "${adapter}" run >/dev/null \
|
|
360
|
+
|| { echo "smoke-trace probe-frame-lock: adapter run failed for ${adapter_id}/${model}" >&2; exit 8; }
|
|
361
|
+
ffmpeg -hide_banner -loglevel error -nostdin -y -i "${clip}" -frames:v 1 -update 1 "${frame0}" \
|
|
362
|
+
|| { echo "smoke-trace probe-frame-lock: could not extract frame 0 from ${clip}" >&2; exit 8; }
|
|
363
|
+
|
|
364
|
+
local psnr verdict
|
|
365
|
+
psnr="$(_st_psnr "${still}" "${frame0}")"
|
|
366
|
+
if _st_ge "${psnr}" "${ST_FRAME0_PSNR_MIN}"; then verdict=true; else verdict=false; fi
|
|
367
|
+
|
|
368
|
+
# Write the probed fact into the manifest. `start_frame` is set from the
|
|
369
|
+
# measurement in BOTH directions — a failed probe writes `false` with the
|
|
370
|
+
# measured value kept, never `null`, because "we looked and it did not hold"
|
|
371
|
+
# is a different fact from "nobody looked".
|
|
372
|
+
local tmp; tmp="$(mktemp)"
|
|
373
|
+
jq --arg m "${model}" --argjson v "${verdict}" --arg p "${psnr}" --arg d "${stamp%T*}" '
|
|
374
|
+
.models[$m].start_frame = $v
|
|
375
|
+
| .models[$m].frame_lock = {probed_at: $d, psnr_frame0: $p}
|
|
376
|
+
' "${manifest}" > "${tmp}" && mv "${tmp}" "${manifest}"
|
|
377
|
+
|
|
378
|
+
local end_note="not probed (no --end-still)"
|
|
379
|
+
if [ -n "${end_still}" ]; then
|
|
380
|
+
local endframe="${clip%.mp4}-endframe.png"
|
|
381
|
+
ffmpeg -hide_banner -loglevel error -nostdin -y -sseof -0.15 -i "${clip}" -frames:v 1 -update 1 "${endframe}" || true
|
|
382
|
+
end_note="end frame extracted to ${endframe} beside ${end_still} — composition is a human judgement, no number recorded"
|
|
383
|
+
fi
|
|
384
|
+
|
|
385
|
+
jq -nc --arg a "${adapter_id}" --arg m "${model}" --arg p "${psnr}" \
|
|
386
|
+
--argjson v "${verdict}" --arg d "${stamp%T*}" --arg clip "${clip}" --arg en "${end_note}" '{
|
|
387
|
+
adapter:$a, model:$m, psnr_frame0:$p, start_frame:$v, probed_at:$d, clip:$clip, end_frame_side:$en
|
|
388
|
+
}'
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
# `cost-ledger append` — the ONLY sanctioned route from a charged figure back
|
|
392
|
+
# into a modeled one (roadmap 2.3).
|
|
393
|
+
#
|
|
394
|
+
# The gap this closes is narrow and was mis-stated before reproduction: the
|
|
395
|
+
# read-back already existed. `lib/resume-scan.sh` reads `cost.json .charged_usd`
|
|
396
|
+
# and sums it as `spent_usd`, and the from-song command writes that file after
|
|
397
|
+
# every live scene. What did NOT exist is any path from that number back into
|
|
398
|
+
# `manifest.cost_per_second_usd` — money was spent, recorded, and never read
|
|
399
|
+
# into the model it contradicted.
|
|
400
|
+
#
|
|
401
|
+
# `charged` is `null`, never `0`, when nothing was charged or the charge is
|
|
402
|
+
# unknown. A missing price and a free render are different facts, and `0` erases
|
|
403
|
+
# the difference in the one direction that silently lowers every future
|
|
404
|
+
# estimate. `--charged` accepts the literal `null` for exactly this reason.
|
|
405
|
+
_st_cost_ledger() {
|
|
406
|
+
local sub="${1:-}"; shift || true
|
|
407
|
+
local ledger="${ROOT}/agents/evidence/ai-video/cost-ledger.jsonl"
|
|
408
|
+
case "${sub}" in
|
|
409
|
+
append)
|
|
410
|
+
local adapter="" model="" modeled="null" charged="null" note="" date_s="" out=""
|
|
411
|
+
while [ $# -gt 0 ]; do
|
|
412
|
+
case "$1" in
|
|
413
|
+
--adapter) adapter="${2:-}"; shift 2 ;;
|
|
414
|
+
--model) model="${2:-}"; shift 2 ;;
|
|
415
|
+
--modeled) modeled="${2:-null}"; shift 2 ;;
|
|
416
|
+
--charged) charged="${2:-null}"; shift 2 ;;
|
|
417
|
+
--note) note="${2:-}"; shift 2 ;;
|
|
418
|
+
--date) date_s="${2:-}"; shift 2 ;;
|
|
419
|
+
--ledger) ledger="${2:-}"; shift 2 ;;
|
|
420
|
+
*) echo "smoke-trace cost-ledger append: unknown arg '$1'" >&2; exit 2 ;;
|
|
421
|
+
esac
|
|
422
|
+
done
|
|
423
|
+
[ -n "${adapter}" ] && [ -n "${model}" ] \
|
|
424
|
+
|| { echo "usage: smoke-trace.sh cost-ledger append --adapter <id> --model <id> [--modeled <usd>] [--charged <usd|null>] [--note <text>]" >&2; exit 2; }
|
|
425
|
+
[ -n "${date_s}" ] || date_s="$(date -u +%Y-%m-%d)"
|
|
426
|
+
# An empty string is NOT zero and is NOT a number: normalise it to null
|
|
427
|
+
# rather than letting jq coerce it.
|
|
428
|
+
[ -n "${modeled}" ] || modeled="null"
|
|
429
|
+
[ -n "${charged}" ] || charged="null"
|
|
430
|
+
out="$(jq -nc --arg a "${adapter}" --arg m "${model}" --arg d "${date_s}" --arg n "${note}" \
|
|
431
|
+
--argjson modeled "${modeled}" --argjson charged "${charged}" '{
|
|
432
|
+
adapter:$a, model:$m, modeled:$modeled, charged:$charged, date:$d
|
|
433
|
+
} + (if $n == "" then {} else {note:$n} end)')" \
|
|
434
|
+
|| { echo "smoke-trace cost-ledger: --modeled/--charged must be a number or the literal null" >&2; exit 7; }
|
|
435
|
+
mkdir -p "$(dirname "${ledger}")"
|
|
436
|
+
printf '%s\n' "${out}" >> "${ledger}"
|
|
437
|
+
printf '%s\n' "${out}"
|
|
438
|
+
;;
|
|
439
|
+
"") echo "usage: smoke-trace.sh cost-ledger append …" >&2; exit 2 ;;
|
|
440
|
+
*) echo "smoke-trace cost-ledger: unknown subcommand '${sub}'" >&2; exit 2 ;;
|
|
441
|
+
esac
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
case "${1:-}" in
|
|
445
|
+
index) shift; _st_index "$@"; exit 0 ;;
|
|
446
|
+
cost-ledger) shift; _st_cost_ledger "$@"; exit 0 ;;
|
|
447
|
+
assumed) shift; _st_assumed "$@"; exit 0 ;;
|
|
448
|
+
psnr) shift; _st_metric psnr "$@"; exit 0 ;;
|
|
449
|
+
ssim) shift; _st_metric ssim "$@"; exit 0 ;;
|
|
450
|
+
frame0) shift; _st_metric frame0 "$@"; exit 0 ;;
|
|
451
|
+
seam-score) shift; _st_seam_score "$@"; exit 0 ;;
|
|
452
|
+
probe-frame-lock) shift; _st_probe_frame_lock "$@"; exit 0 ;;
|
|
453
|
+
esac
|
|
454
|
+
# --- end subcommands ---------------------------------------------------------
|
|
455
|
+
|
|
38
456
|
PROVIDER=""
|
|
39
457
|
MODE="dry-run"
|
|
40
458
|
MODEL=""
|
|
41
459
|
REF_IMAGE=""
|
|
460
|
+
# Comma-separated ASSUMED field names this trace confirms (0.5). Empty is the
|
|
461
|
+
# honest default: a capture confirms nothing until the operator names what it
|
|
462
|
+
# confirmed, and `[]` is what every trace written before this field existed
|
|
463
|
+
# would have carried.
|
|
464
|
+
CONFIRMS=""
|
|
42
465
|
OUT_DIR="${ROOT}/agents/reference/ai-video/smoke-traces"
|
|
43
466
|
while [ $# -gt 0 ]; do
|
|
44
467
|
case "$1" in
|
|
@@ -46,6 +469,7 @@ while [ $# -gt 0 ]; do
|
|
|
46
469
|
--model) MODEL="${2:-}"; shift 2 ;;
|
|
47
470
|
--ref-image) REF_IMAGE="${2:-}"; shift 2 ;;
|
|
48
471
|
--live) MODE="live"; shift ;;
|
|
472
|
+
--confirms) CONFIRMS="${2:-}"; shift 2 ;;
|
|
49
473
|
--out) OUT_DIR="${2:-}"; shift 2 ;;
|
|
50
474
|
*) echo "smoke-trace: unknown arg '$1'" >&2; exit 2 ;;
|
|
51
475
|
esac
|
|
@@ -173,15 +597,39 @@ AUDIO_EMB="$(jq -r 'if .audio_embedded == true then "true" else "false" end' <<<
|
|
|
173
597
|
NOTE="dry-run = plumbing proof (no network/spend); NOT a real validation. Run --live with a provider key for the real smoke trace."
|
|
174
598
|
[ "${MODE}" = "live" ] && NOTE="live round-trip against the real provider API (real spend)."
|
|
175
599
|
|
|
600
|
+
# recheck_by — a vendor capability is a dated observation, never a permanent
|
|
601
|
+
# fact. Endpoints have gained and lost frame conditioning inside a few weeks,
|
|
602
|
+
# so every trace states when its claim stops being evidence. Same idiom as
|
|
603
|
+
# `keep-beta-until` in docs/contracts/skill-bundled-assets.md; the window is
|
|
604
|
+
# ONE constant, shared with lint_adapter_tier.ts's staleness check, so the two
|
|
605
|
+
# cannot drift apart.
|
|
606
|
+
RECHECK_DAYS="${AIV_TRACE_RECHECK_DAYS:-180}"
|
|
607
|
+
RECHECK_BY="$(TS="${TS}" D="${RECHECK_DAYS}" node -e '
|
|
608
|
+
const ts = process.env.TS;
|
|
609
|
+
// Capture stamps are filesystem-safe: 2026-06-10T12-36-49Z -> ISO.
|
|
610
|
+
const iso = ts.replace(/T(\d{2})-(\d{2})-(\d{2})Z$/, "T$1:$2:$3Z");
|
|
611
|
+
const t = new Date(iso);
|
|
612
|
+
if (Number.isNaN(t.getTime())) { process.stdout.write(""); process.exit(0); }
|
|
613
|
+
t.setUTCDate(t.getUTCDate() + Number(process.env.D));
|
|
614
|
+
process.stdout.write(t.toISOString().slice(0, 10));
|
|
615
|
+
')"
|
|
616
|
+
|
|
617
|
+
CONFIRMS_JSON="$(printf '%s' "${CONFIRMS}" | tr ',' '\n' \
|
|
618
|
+
| sed -E 's/^[[:space:]]*//; s/[[:space:]]*$//' | sed '/^$/d' \
|
|
619
|
+
| jq -R . | jq -sc .)"
|
|
620
|
+
|
|
176
621
|
jq -n \
|
|
177
622
|
--arg provider "${PROVIDER}" --arg tier "${TIER}" --arg mode "${MODE}" \
|
|
178
623
|
--arg ts "${TS}" --argjson phases "${PHASES}" \
|
|
179
624
|
--arg video "${VIDEO_PATH}" --arg artifact_ok "${ARTIFACT_OK}" \
|
|
180
625
|
--arg cost "${COST}" --argjson audio "${AUDIO_EMB}" \
|
|
181
626
|
--argjson success "${SUCCESS}" --arg note "${NOTE}" \
|
|
627
|
+
--arg recheck "${RECHECK_BY}" --argjson confirms "${CONFIRMS_JSON}" \
|
|
182
628
|
'{provider:$provider, lifecycle_tier:$tier, mode:$mode, captured_utc:$ts,
|
|
183
|
-
success:$success, video_path:$video,
|
|
184
|
-
|
|
629
|
+
recheck_by:$recheck, success:$success, video_path:$video,
|
|
630
|
+
artifact_path_validated:$artifact_ok, cost_estimate:$cost,
|
|
631
|
+
audio_embedded:$audio, assumed_fields_confirmed:$confirms,
|
|
632
|
+
phases:$phases, note:$note}' \
|
|
185
633
|
> "${TRACE}"
|
|
186
634
|
|
|
187
635
|
echo "smoke-trace: ${MODE} ${PROVIDER} (tier=${TIER}) success=${SUCCESS} → ${TRACE#"${ROOT}/"}"
|