@event4u/agent-config 1.16.0 → 1.18.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/.agent-src/commands/{agents-audit.md → agents/audit.md} +4 -3
- package/.agent-src/commands/{agents-cleanup.md → agents/cleanup.md} +12 -6
- package/.agent-src/commands/{agents-prepare.md → agents/prepare.md} +4 -3
- package/.agent-src/commands/agents.md +46 -0
- package/.agent-src/commands/{chat-history-checkpoint.md → chat-history/checkpoint.md} +4 -4
- package/.agent-src/commands/{chat-history-clear.md → chat-history/clear.md} +4 -4
- package/.agent-src/commands/{chat-history-resume.md → chat-history/resume.md} +4 -4
- package/.agent-src/commands/chat-history/show.md +107 -0
- package/.agent-src/commands/chat-history.md +33 -89
- package/.agent-src/commands/{commit-in-chunks.md → commit/in-chunks.md} +15 -13
- package/.agent-src/commands/commit.md +22 -2
- package/.agent-src/commands/{context-create.md → context/create.md} +4 -3
- package/.agent-src/commands/{context-refactor.md → context/refactor.md} +4 -3
- package/.agent-src/commands/context.md +44 -0
- package/.agent-src/commands/{copilot-agents-init.md → copilot-agents/init.md} +4 -3
- package/.agent-src/commands/{copilot-agents-optimize.md → copilot-agents/optimize.md} +4 -3
- package/.agent-src/commands/copilot-agents.md +44 -0
- package/.agent-src/commands/council/default.md +221 -0
- package/.agent-src/commands/{council-design.md → council/design.md} +6 -5
- package/.agent-src/commands/{council-optimize.md → council/optimize.md} +7 -6
- package/.agent-src/commands/{council-pr.md → council/pr.md} +6 -5
- package/.agent-src/commands/council.md +47 -212
- package/.agent-src/commands/{create-pr-description.md → create-pr/description-only.md} +4 -2
- package/.agent-src/commands/create-pr.md +26 -5
- package/.agent-src/commands/{feature-dev.md → feature/dev.md} +5 -10
- package/.agent-src/commands/{feature-explore.md → feature/explore.md} +4 -8
- package/.agent-src/commands/{feature-plan.md → feature/plan.md} +4 -8
- package/.agent-src/commands/{feature-refactor.md → feature/refactor.md} +4 -8
- package/.agent-src/commands/{feature-roadmap.md → feature/roadmap.md} +6 -10
- package/.agent-src/commands/feature.md +6 -12
- package/.agent-src/commands/{fix-ci.md → fix/ci.md} +4 -8
- package/.agent-src/commands/{fix-portability.md → fix/portability.md} +4 -8
- package/.agent-src/commands/{fix-pr-bot-comments.md → fix/pr-bots.md} +4 -8
- package/.agent-src/commands/{fix-pr-developer-comments.md → fix/pr-developers.md} +4 -8
- package/.agent-src/commands/{fix-pr-comments.md → fix/pr.md} +7 -11
- package/.agent-src/commands/{fix-references.md → fix/refs.md} +4 -8
- package/.agent-src/commands/{fix-seeder.md → fix/seeder.md} +4 -8
- package/.agent-src/commands/fix.md +7 -13
- package/.agent-src/commands/{do-and-judge.md → judge/on-diff.md} +4 -3
- package/.agent-src/commands/judge/solo.md +90 -0
- package/.agent-src/commands/{do-in-steps.md → judge/steps.md} +4 -3
- package/.agent-src/commands/judge.md +35 -70
- package/.agent-src/commands/{memory-add.md → memory/add.md} +4 -3
- package/.agent-src/commands/{memory-full.md → memory/load.md} +4 -3
- package/.agent-src/commands/{memory-promote.md → memory/promote.md} +4 -3
- package/.agent-src/commands/{propose-memory.md → memory/propose.md} +4 -3
- package/.agent-src/commands/memory.md +48 -0
- package/.agent-src/commands/{module-create.md → module/create.md} +4 -3
- package/.agent-src/commands/{module-explore.md → module/explore.md} +4 -3
- package/.agent-src/commands/module.md +44 -0
- package/.agent-src/commands/{optimize-agents.md → optimize/agents.md} +4 -8
- package/.agent-src/commands/{optimize-augmentignore.md → optimize/augmentignore.md} +4 -9
- package/.agent-src/commands/{optimize-rtk-filters.md → optimize/rtk.md} +4 -8
- package/.agent-src/commands/{optimize-skills.md → optimize/skills.md} +4 -8
- package/.agent-src/commands/optimize.md +4 -10
- package/.agent-src/commands/{override-create.md → override/create.md} +4 -3
- package/.agent-src/commands/{override-manage.md → override/manage.md} +4 -3
- package/.agent-src/commands/override.md +44 -0
- package/.agent-src/commands/{roadmap-create.md → roadmap/create.md} +4 -3
- package/.agent-src/commands/{roadmap-execute.md → roadmap/execute.md} +4 -3
- package/.agent-src/commands/roadmap.md +44 -0
- package/.agent-src/commands/{tests-create.md → tests/create.md} +4 -3
- package/.agent-src/commands/{tests-execute.md → tests/execute.md} +4 -3
- package/.agent-src/commands/tests.md +44 -0
- package/.agent-src/contexts/communication/rules-auto/artifact-engagement-recording-mechanics.md +72 -0
- package/.agent-src/contexts/communication/rules-auto/augment-portability-mechanics.md +79 -0
- package/.agent-src/contexts/communication/rules-auto/augment-source-of-truth-mechanics.md +98 -0
- package/.agent-src/contexts/communication/rules-auto/cli-output-handling-mechanics.md +87 -0
- package/.agent-src/contexts/communication/rules-auto/command-suggestion-policy-mechanics.md +62 -0
- package/.agent-src/contexts/communication/rules-auto/docs-sync-mechanics.md +78 -0
- package/.agent-src/contexts/communication/rules-auto/package-ci-checks-mechanics.md +85 -0
- package/.agent-src/contexts/communication/rules-auto/review-routing-awareness-mechanics.md +65 -0
- package/.agent-src/contexts/communication/rules-auto/roadmap-progress-sync-mechanics.md +78 -0
- package/.agent-src/contexts/communication/rules-auto/skill-quality-mechanics.md +62 -0
- package/.agent-src/contexts/communication/rules-auto/slash-command-routing-policy-mechanics.md +55 -0
- package/.agent-src/contexts/communication/rules-auto/ui-audit-gate-mechanics.md +53 -0
- package/.agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +77 -0
- package/.agent-src/contexts/judges/no-consolidate-rationale.md +102 -0
- package/.agent-src/contexts/judges/persona-voice-rubric.md +140 -0
- package/.agent-src/rules/artifact-engagement-recording.md +13 -69
- package/.agent-src/rules/ask-when-uncertain.md +27 -42
- package/.agent-src/rules/augment-portability.md +15 -61
- package/.agent-src/rules/augment-source-of-truth.md +27 -93
- package/.agent-src/rules/cli-output-handling.md +10 -76
- package/.agent-src/rules/command-suggestion-policy.md +18 -59
- package/.agent-src/rules/commit-conventions.md +17 -14
- package/.agent-src/rules/context-hygiene.md +6 -0
- package/.agent-src/rules/direct-answers.md +35 -59
- package/.agent-src/rules/docker-commands.md +5 -5
- package/.agent-src/rules/docs-sync.md +15 -69
- package/.agent-src/rules/language-and-tone.md +48 -72
- package/.agent-src/rules/missing-tool-handling.md +28 -22
- package/.agent-src/rules/no-cheap-questions.md +39 -53
- package/.agent-src/rules/no-roadmap-references.md +73 -0
- package/.agent-src/rules/onboarding-gate.md +7 -0
- package/.agent-src/rules/package-ci-checks.md +21 -61
- package/.agent-src/rules/preservation-guard.md +64 -29
- package/.agent-src/rules/review-routing-awareness.md +24 -43
- package/.agent-src/rules/roadmap-progress-sync.md +31 -65
- package/.agent-src/rules/rule-type-governance.md +28 -0
- package/.agent-src/rules/security-sensitive-stop.md +8 -8
- package/.agent-src/rules/skill-quality.md +16 -48
- package/.agent-src/rules/slash-command-routing-policy.md +7 -4
- package/.agent-src/rules/think-before-action.md +52 -42
- package/.agent-src/rules/tool-safety.md +19 -16
- package/.agent-src/rules/ui-audit-gate.md +24 -38
- package/.agent-src/rules/user-interaction.md +13 -68
- package/.agent-src/skills/ai-council/SKILL.md +2 -0
- package/.agent-src/skills/api-testing/SKILL.md +1 -1
- package/.agent-src/skills/check-refs/SKILL.md +59 -40
- package/.agent-src/skills/conventional-commits-writing/SKILL.md +86 -28
- package/.agent-src/skills/copilot-agents-optimization/SKILL.md +5 -5
- package/.agent-src/skills/developer-like-execution/SKILL.md +4 -4
- package/.agent-src/skills/finishing-a-development-branch/SKILL.md +101 -65
- package/.agent-src/skills/flux/SKILL.md +30 -10
- package/.agent-src/skills/github-ci/SKILL.md +2 -2
- package/.agent-src/skills/judge-code-quality/SKILL.md +7 -8
- package/.agent-src/skills/judge-security-auditor/SKILL.md +4 -5
- package/.agent-src/skills/judge-test-coverage/SKILL.md +3 -4
- package/.agent-src/skills/lint-skills/SKILL.md +57 -39
- package/.agent-src/skills/md-language-check/SKILL.md +61 -39
- package/.agent-src/skills/override-management/SKILL.md +5 -5
- package/.agent-src/skills/quality-tools/SKILL.md +2 -2
- package/.agent-src/skills/react-shadcn-ui/SKILL.md +116 -43
- package/.agent-src/skills/readme-reviewer/SKILL.md +30 -29
- package/.agent-src/skills/readme-writing/SKILL.md +78 -53
- package/.agent-src/skills/readme-writing-package/SKILL.md +50 -47
- package/.agent-src/skills/receiving-code-review/SKILL.md +52 -47
- package/.agent-src/skills/refine-prompt/SKILL.md +0 -1
- package/.agent-src/skills/requesting-code-review/SKILL.md +35 -30
- package/.agent-src/skills/security/SKILL.md +7 -2
- package/.agent-src/skills/security-audit/SKILL.md +7 -3
- package/.agent-src/skills/systematic-debugging/SKILL.md +68 -60
- package/.agent-src/skills/test-driven-development/SKILL.md +59 -57
- package/.agent-src/skills/test-performance/SKILL.md +0 -1
- package/.agent-src/skills/traefik/SKILL.md +4 -4
- package/.agent-src/skills/verify-completion-evidence/SKILL.md +28 -26
- package/.agent-src/templates/roadmaps.md +4 -0
- package/.claude-plugin/marketplace.json +22 -11
- package/AGENTS.md +2 -2
- package/CHANGELOG.md +125 -1
- package/README.md +18 -17
- package/docs/architecture.md +4 -6
- package/docs/catalog.md +67 -39
- package/docs/contracts/STABILITY.md +13 -7
- package/docs/contracts/adr-chat-history-split.md +1 -3
- package/docs/contracts/adr-command-suggestion.md +0 -2
- package/docs/contracts/adr-implement-ticket-runtime.md +1 -2
- package/docs/contracts/adr-product-ui-track.md +3 -6
- package/docs/contracts/adr-prompt-driven-execution.md +3 -4
- package/docs/contracts/agent-memory-contract.md +6 -11
- package/docs/contracts/artifact-engagement-flow.md +6 -9
- package/docs/contracts/command-clusters.md +56 -46
- package/docs/contracts/command-suggestion-flow.md +1 -3
- package/docs/contracts/context-paths.md +99 -0
- package/docs/contracts/file-ownership-matrix.json +6722 -0
- package/docs/contracts/file-ownership-matrix.md +134 -0
- package/docs/contracts/implement-ticket-flow.md +6 -9
- package/docs/contracts/linear-ai-rules-inclusion.md +0 -1
- package/docs/contracts/linear-ai-three-layers.md +0 -2
- package/docs/contracts/load-context-budget-model.md +258 -0
- package/docs/contracts/load-context-schema.md +21 -3
- package/docs/contracts/roadmap-complexity-standard.md +137 -0
- package/docs/contracts/rule-interactions.md +0 -1
- package/docs/contracts/rule-priority-hierarchy.md +1 -1
- package/docs/contracts/ui-track-flow.md +7 -17
- package/docs/customization.md +2 -0
- package/docs/getting-started.md +5 -4
- package/docs/guidelines/agent-infra/ask-when-uncertain-demos.md +134 -0
- package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +100 -0
- package/docs/guidelines/agent-infra/direct-answers-demos.md +145 -0
- package/docs/guidelines/agent-infra/verify-before-complete-demos.md +128 -0
- package/package.json +1 -1
- package/scripts/_phase2_shim_helper.py +109 -0
- package/scripts/agent-config +30 -0
- package/scripts/ai_council/one_off_archive/2026-05/README.md +45 -0
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_2a4_acceptance.py +208 -0
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_budget_v2_audit.py +206 -0
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_context_layer_v1_estimate.py +67 -0
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_context_layer_v1_review.py +292 -0
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_followups_review.py +259 -0
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_nondestructive_inline_audit.py +209 -0
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_phase4_dispatch_latency.py +108 -0
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_phase6_trigger_jaccard.py +92 -0
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_phase_2a_budget_rebalance.py +257 -0
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_phase_2a_post_revert.py +197 -0
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_rule_hardening_v1.py +251 -0
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_structural_open_questions.py +232 -0
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_structural_optimization.py +144 -0
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_structural_v3_gaps.py +252 -0
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_structural_v3_review.py +240 -0
- package/scripts/build_rule_trigger_matrix.py +360 -0
- package/scripts/check_always_budget.py +402 -45
- package/scripts/check_cluster_patterns.py +159 -0
- package/scripts/check_command_count_messaging.py +14 -7
- package/scripts/check_context_paths.py +201 -0
- package/scripts/check_no_roadmap_refs.py +155 -0
- package/scripts/check_one_off_location.py +81 -0
- package/scripts/check_phase_coupling.py +148 -0
- package/scripts/check_portability.py +2 -0
- package/scripts/check_references.py +35 -2
- package/scripts/check_safety_floor_untouched.py +125 -0
- package/scripts/command_suggester/loader.py +4 -1
- package/scripts/compress.py +64 -15
- package/scripts/context_hygiene_hook.py +173 -0
- package/scripts/generate_index.py +6 -2
- package/scripts/generate_ownership_matrix.py +323 -0
- package/scripts/hooks/augment-context-hygiene.sh +55 -0
- package/scripts/hooks/augment-onboarding-gate.sh +55 -0
- package/scripts/hooks/augment-roadmap-progress.sh +57 -0
- package/scripts/install.py +105 -45
- package/scripts/lint_examples.py +98 -0
- package/scripts/lint_no_new_atomic_commands.py +12 -11
- package/scripts/lint_roadmap_complexity.py +127 -0
- package/scripts/onboarding_gate_hook.py +137 -0
- package/scripts/requirements-evals.txt +1 -0
- package/scripts/roadmap_progress_hook.py +159 -0
- package/scripts/schemas/command.schema.json +4 -3
- package/scripts/schemas/rule.schema.json +5 -0
- package/scripts/skill_linter.py +1 -0
- package/scripts/sync_agent_settings.py +25 -2
- package/scripts/update_counts.py +7 -0
- /package/scripts/ai_council/{_one_off_rebalancing_audit.py → one_off_archive/2026-05/_one_off_rebalancing_audit.py} +0 -0
- /package/scripts/ai_council/{_one_off_roundtrip.py → one_off_archive/2026-05/_one_off_roundtrip.py} +0 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""One-shot helper: add `superseded_by:` + `deprecated_in:` + warning
|
|
3
|
+
banner to Phase 2 atomic-command shims.
|
|
4
|
+
|
|
5
|
+
Idempotent — if a file already has `superseded_by:` set, it is skipped.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
# (file-stem, "<cluster> <sub>") — "<cluster> --flag" for flag-based
|
|
12
|
+
PHASE2_SHIMS: list[tuple[str, str]] = [
|
|
13
|
+
# chat-history cluster
|
|
14
|
+
("chat-history-resume", "chat-history resume"),
|
|
15
|
+
("chat-history-clear", "chat-history clear"),
|
|
16
|
+
("chat-history-checkpoint", "chat-history checkpoint"),
|
|
17
|
+
# agents cluster
|
|
18
|
+
("agents-audit", "agents audit"),
|
|
19
|
+
("agents-cleanup", "agents cleanup"),
|
|
20
|
+
("agents-prepare", "agents prepare"),
|
|
21
|
+
# memory cluster
|
|
22
|
+
("memory-add", "memory add"),
|
|
23
|
+
("memory-full", "memory load"),
|
|
24
|
+
("memory-promote", "memory promote"),
|
|
25
|
+
("propose-memory", "memory propose"),
|
|
26
|
+
# roadmap cluster
|
|
27
|
+
("roadmap-create", "roadmap create"),
|
|
28
|
+
("roadmap-execute", "roadmap execute"),
|
|
29
|
+
# module cluster
|
|
30
|
+
("module-create", "module create"),
|
|
31
|
+
("module-explore", "module explore"),
|
|
32
|
+
# tests cluster
|
|
33
|
+
("tests-create", "tests create"),
|
|
34
|
+
("tests-execute", "tests execute"),
|
|
35
|
+
# context cluster
|
|
36
|
+
("context-create", "context create"),
|
|
37
|
+
("context-refactor", "context refactor"),
|
|
38
|
+
# override cluster
|
|
39
|
+
("override-create", "override create"),
|
|
40
|
+
("override-manage", "override manage"),
|
|
41
|
+
# copilot-agents cluster
|
|
42
|
+
("copilot-agents-init", "copilot-agents init"),
|
|
43
|
+
("copilot-agents-optimize", "copilot-agents optimize"),
|
|
44
|
+
# judge cluster (do-and-judge / do-in-steps now sub-commands)
|
|
45
|
+
("do-and-judge", "judge on-diff"),
|
|
46
|
+
("do-in-steps", "judge steps"),
|
|
47
|
+
# commit / create-pr — flag-based clusters
|
|
48
|
+
("commit-in-chunks", "commit --in-chunks"),
|
|
49
|
+
("create-pr-description", "create-pr --description-only"),
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
DEPRECATED_IN = "1.17.0"
|
|
53
|
+
COMMANDS_DIR = Path(".agent-src.uncompressed/commands")
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def patch_file(stem: str, target: str) -> str:
|
|
57
|
+
path = COMMANDS_DIR / f"{stem}.md"
|
|
58
|
+
if not path.exists():
|
|
59
|
+
return f"SKIP {stem}: not found"
|
|
60
|
+
text = path.read_text(encoding="utf-8")
|
|
61
|
+
if "superseded_by:" in text.split("---", 2)[1] if text.startswith("---") else False:
|
|
62
|
+
return f"SKIP {stem}: already shimmed"
|
|
63
|
+
|
|
64
|
+
if not text.startswith("---\n"):
|
|
65
|
+
return f"SKIP {stem}: no frontmatter"
|
|
66
|
+
end = text.find("\n---\n", 4)
|
|
67
|
+
if end == -1:
|
|
68
|
+
return f"SKIP {stem}: malformed frontmatter"
|
|
69
|
+
fm_block = text[4:end]
|
|
70
|
+
body = text[end + len("\n---\n"):]
|
|
71
|
+
|
|
72
|
+
if "superseded_by:" in fm_block:
|
|
73
|
+
return f"SKIP {stem}: already shimmed"
|
|
74
|
+
|
|
75
|
+
new_fm_lines = fm_block.rstrip("\n").splitlines()
|
|
76
|
+
new_fm_lines.append(f"superseded_by: {target}")
|
|
77
|
+
new_fm_lines.append(f'deprecated_in: "{DEPRECATED_IN}"')
|
|
78
|
+
new_fm = "\n".join(new_fm_lines)
|
|
79
|
+
|
|
80
|
+
is_flag = target.startswith(("commit ", "create-pr "))
|
|
81
|
+
if is_flag:
|
|
82
|
+
cluster_invocation = f"/{target}"
|
|
83
|
+
else:
|
|
84
|
+
cluster_invocation = f"/{target}"
|
|
85
|
+
banner = (
|
|
86
|
+
f"> ⚠️ /{stem} is deprecated; use {cluster_invocation} instead.\n"
|
|
87
|
+
f"> This shim is retained for one release cycle "
|
|
88
|
+
f"({DEPRECATED_IN} → next minor) and forwards to the same "
|
|
89
|
+
f"instructions below. See "
|
|
90
|
+
f"[`docs/contracts/command-clusters.md`]"
|
|
91
|
+
f"(../../docs/contracts/command-clusters.md).\n\n"
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
new_text = f"---\n{new_fm}\n---\n\n{banner}{body.lstrip(chr(10))}"
|
|
95
|
+
path.write_text(new_text, encoding="utf-8")
|
|
96
|
+
return f"OK {stem} → {target}"
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def main() -> int:
|
|
100
|
+
results = []
|
|
101
|
+
for stem, target in PHASE2_SHIMS:
|
|
102
|
+
results.append(patch_file(stem, target))
|
|
103
|
+
for r in results:
|
|
104
|
+
print(r)
|
|
105
|
+
return 0
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
if __name__ == "__main__":
|
|
109
|
+
sys.exit(main())
|
package/scripts/agent-config
CHANGED
|
@@ -70,6 +70,12 @@ Commands:
|
|
|
70
70
|
Usage: chat-history:hook --platform <claude|augment|cursor|cline|windsurf|gemini>
|
|
71
71
|
chat-history:checkpoint Append a phase-boundary entry to .agent-chat-history
|
|
72
72
|
(CHECKPOINT fallback for platforms without native hooks)
|
|
73
|
+
roadmap-progress:hook PostToolUse hook entry point (read JSON from stdin)
|
|
74
|
+
Regenerates roadmaps-progress.md when a tool wrote under agents/roadmaps/
|
|
75
|
+
onboarding-gate:hook Hook entry point (drains stdin)
|
|
76
|
+
Writes .augment/state/onboarding-gate.json from .agent-settings.yml
|
|
77
|
+
context-hygiene:hook PostToolUse hook entry point (read JSON from stdin)
|
|
78
|
+
Maintains .augment/state/context-hygiene.json (turn count, loop, freshness)
|
|
73
79
|
telemetry:record Append one artefact-engagement event (default-off)
|
|
74
80
|
telemetry:status Print artefact-engagement telemetry status (read-only)
|
|
75
81
|
telemetry:report Aggregate the engagement log into a quartile report
|
|
@@ -316,6 +322,27 @@ cmd_chat_history_hook() {
|
|
|
316
322
|
exec python3 "$script" hook-dispatch "$@"
|
|
317
323
|
}
|
|
318
324
|
|
|
325
|
+
cmd_roadmap_progress_hook() {
|
|
326
|
+
require_python3
|
|
327
|
+
local script
|
|
328
|
+
script="$(resolve_script "scripts/roadmap_progress_hook.py")" || return 1
|
|
329
|
+
exec python3 "$script" "$@"
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
cmd_onboarding_gate_hook() {
|
|
333
|
+
require_python3
|
|
334
|
+
local script
|
|
335
|
+
script="$(resolve_script "scripts/onboarding_gate_hook.py")" || return 1
|
|
336
|
+
exec python3 "$script" "$@"
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
cmd_context_hygiene_hook() {
|
|
340
|
+
require_python3
|
|
341
|
+
local script
|
|
342
|
+
script="$(resolve_script "scripts/context_hygiene_hook.py")" || return 1
|
|
343
|
+
exec python3 "$script" "$@"
|
|
344
|
+
}
|
|
345
|
+
|
|
319
346
|
cmd_chat_history_checkpoint() {
|
|
320
347
|
require_python3
|
|
321
348
|
local script
|
|
@@ -436,6 +463,9 @@ main() {
|
|
|
436
463
|
refine-ticket:detect) cmd_refine_ticket_detect "$@" ;;
|
|
437
464
|
chat-history:hook) cmd_chat_history_hook "$@" ;;
|
|
438
465
|
chat-history:checkpoint) cmd_chat_history_checkpoint "$@" ;;
|
|
466
|
+
roadmap-progress:hook) cmd_roadmap_progress_hook "$@" ;;
|
|
467
|
+
onboarding-gate:hook) cmd_onboarding_gate_hook "$@" ;;
|
|
468
|
+
context-hygiene:hook) cmd_context_hygiene_hook "$@" ;;
|
|
439
469
|
telemetry:record) cmd_telemetry_record "$@" ;;
|
|
440
470
|
telemetry:status) cmd_telemetry_status "$@" ;;
|
|
441
471
|
telemetry:report) cmd_telemetry_report "$@" ;;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# One-off archive — 2026-05
|
|
2
|
+
|
|
3
|
+
> Archived per **Phase 0a.2** of `agents/roadmaps/road-to-rule-hardening.md`.
|
|
4
|
+
> Each script here was a single-purpose AI-council probe or measurement
|
|
5
|
+
> tied to a specific phase of `road-to-structural-optimization.md` (now
|
|
6
|
+
> archived) or `road-to-rule-hardening.md`. The session output lives
|
|
7
|
+
> under `agents/council-sessions/` (durable evidence) and the linter
|
|
8
|
+
> `scripts/check_one_off_location.py` enforces that no new
|
|
9
|
+
> `_one_off_*.py` lands outside this folder.
|
|
10
|
+
|
|
11
|
+
## Lifecycle rule (uniform — Phase 0.2 of context-layer-maturity)
|
|
12
|
+
|
|
13
|
+
> A one-off is **archived**, never deleted. The session manifest under
|
|
14
|
+
> `agents/council-sessions/` is the audit trail; the script itself is
|
|
15
|
+
> kept here so a future contributor can re-read intent, re-run a probe
|
|
16
|
+
> on a future branch, or extract a reusable helper.
|
|
17
|
+
|
|
18
|
+
## Inventory
|
|
19
|
+
|
|
20
|
+
| Script | Roadmap / Phase | Council session id |
|
|
21
|
+
|---|---|---|
|
|
22
|
+
| `_one_off_2a4_acceptance.py` | structural-optimization 2A.4 | various 2A sessions |
|
|
23
|
+
| `_one_off_context_layer_v1_estimate.py` | context-layer-maturity v1 cost estimate | `2026-05-03T17-56-21Z` |
|
|
24
|
+
| `_one_off_context_layer_v1_review.py` | context-layer-maturity v1 review | `2026-05-03T17-56-21Z` |
|
|
25
|
+
| `_one_off_followups_review.py` | road-to-1-16-followups review | session under `agents/council-sessions/` |
|
|
26
|
+
| `_one_off_nondestructive_inline_audit.py` | non-destructive-by-default audit | session under `agents/council-sessions/` |
|
|
27
|
+
| `_one_off_phase4_dispatch_latency.py` | structural-optimization 4.3.1 cluster latency benchmark | local benchmark, no council |
|
|
28
|
+
| `_one_off_phase6_trigger_jaccard.py` | structural-optimization Phase 6 trigger overlap | local measurement |
|
|
29
|
+
| `_one_off_phase_2a_budget_rebalance.py` | structural-optimization 2A budget rebalance | `2026-05-03T*` |
|
|
30
|
+
| `_one_off_phase_2a_post_revert.py` | structural-optimization 2A post-revert | `2026-05-03T*` |
|
|
31
|
+
| `_one_off_rebalancing_audit.py` | rebalancing roadmap audit | session under `agents/council-sessions/` |
|
|
32
|
+
| `_one_off_roundtrip.py` | council client roundtrip smoke test | local smoke test |
|
|
33
|
+
| `_one_off_rule_hardening_v1.py` | rule-hardening v1 review | `2026-05-03T19-16-25Z` |
|
|
34
|
+
| `_one_off_structural_open_questions.py` | structural-optimization open questions | session under `agents/council-sessions/` |
|
|
35
|
+
| `_one_off_structural_optimization.py` | structural-optimization initial review | session under `agents/council-sessions/` |
|
|
36
|
+
| `_one_off_structural_v3_gaps.py` | structural-optimization v3 gap audit | session under `agents/council-sessions/` |
|
|
37
|
+
| `_one_off_structural_v3_review.py` | structural-optimization v3 review | session under `agents/council-sessions/` |
|
|
38
|
+
|
|
39
|
+
## Re-running an archived script
|
|
40
|
+
|
|
41
|
+
Imports may have shifted (e.g. `scripts.ai_council.*`). If a probe
|
|
42
|
+
needs to be re-run against a current branch, copy it back to its
|
|
43
|
+
original location, fix imports, run, then move the working copy
|
|
44
|
+
back here. Do **not** edit in place — keep the archive immutable
|
|
45
|
+
beyond cosmetic README updates.
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"""Council acceptance review of Phase 0.4 2A.4 worked example.
|
|
2
|
+
|
|
3
|
+
Purpose: Phase 0.4.3 of road-to-structural-optimization.md requires a
|
|
4
|
+
council acceptance pass on the 2A.4 obligation-keyword-diff contract
|
|
5
|
+
before Phase 2A may begin. The artefact lives at
|
|
6
|
+
`agents/roadmaps/structural-optimization-2A4-example.md` plus two
|
|
7
|
+
sandbox files. Status will move from `draft` to `locked` only on
|
|
8
|
+
ACCEPT or ACCEPT_WITH_REVISIONS where revisions are minor.
|
|
9
|
+
|
|
10
|
+
Invocation:
|
|
11
|
+
.venv/bin/python -m scripts.ai_council._one_off_2a4_acceptance
|
|
12
|
+
"""
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import sys
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
from scripts.ai_council.bundler import bundle_files
|
|
19
|
+
from scripts.ai_council.clients import (
|
|
20
|
+
AnthropicClient,
|
|
21
|
+
OpenAIClient,
|
|
22
|
+
load_anthropic_key,
|
|
23
|
+
load_openai_key,
|
|
24
|
+
)
|
|
25
|
+
from scripts.ai_council.orchestrator import (
|
|
26
|
+
CostBudget,
|
|
27
|
+
CouncilQuestion,
|
|
28
|
+
consult,
|
|
29
|
+
estimate,
|
|
30
|
+
)
|
|
31
|
+
from scripts.ai_council.pricing import estimate_cost, load_prices
|
|
32
|
+
from scripts.ai_council.project_context import detect_project_context
|
|
33
|
+
from scripts.ai_council.session import SessionManifest, save as save_session
|
|
34
|
+
|
|
35
|
+
REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
36
|
+
ARTEFACTS = [
|
|
37
|
+
REPO_ROOT / "agents/roadmaps/structural-optimization-2A4-example.md",
|
|
38
|
+
REPO_ROOT / "agents/roadmaps/examples/2A4-direct-answers/direct-answers.slim.md",
|
|
39
|
+
REPO_ROOT / "agents/roadmaps/examples/2A4-direct-answers/direct-answers-mechanics.md",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
ORIGINAL_ASK = (
|
|
43
|
+
"Phase 0.4 of road-to-structural-optimization v3.1 dry-runs the "
|
|
44
|
+
"2A.4 obligation-keyword-diff contract on `direct-answers.md` to "
|
|
45
|
+
"lock the contract before Phase 2A begins. The artefact and two "
|
|
46
|
+
"sandbox files (slim rule + extracted mechanics) are presented. "
|
|
47
|
+
"Council task: ACCEPT / ACCEPT_WITH_REVISIONS / REJECT the "
|
|
48
|
+
"contract for use across the remaining 8 always-rules in Phase 2A."
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
REVIEW_PROMPT = """\
|
|
52
|
+
# Council Acceptance Review — 2A.4 Worked Example
|
|
53
|
+
|
|
54
|
+
## Context
|
|
55
|
+
|
|
56
|
+
The host agent ran Phase 0.4 of `road-to-structural-optimization` v3.1: \
|
|
57
|
+
took one always-rule (`direct-answers.md`, smallest of the top-3), split \
|
|
58
|
+
it into a slim RULE+LOGIC half and a MECHANICS context, then applied \
|
|
59
|
+
the 2A.4 obligation-keyword diff contract. The artefact is the report \
|
|
60
|
+
of that dry-run; the two sandbox files are the actual produced split.
|
|
61
|
+
|
|
62
|
+
You are not asked to re-litigate the v3.1 roadmap or the choice of \
|
|
63
|
+
`direct-answers.md` — both were settled in earlier rounds. Verdict \
|
|
64
|
+
solely concerns whether the **contract** (keyword × counts × \
|
|
65
|
+
accept-rationale table, plus its tie-break rules) is now ready to be \
|
|
66
|
+
applied to the remaining 8 always-rules in Phase 2A.
|
|
67
|
+
|
|
68
|
+
## Output Contract (STRICT)
|
|
69
|
+
|
|
70
|
+
Produce exactly these blocks in order. Be decisive — total response \
|
|
71
|
+
budget <= 1200 words.
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
### Contract correctness
|
|
75
|
+
|
|
76
|
+
**Verdict:** <ACCEPT | ACCEPT_WITH_REVISIONS | REJECT>
|
|
77
|
+
**Keyword extraction completeness:** <COMPLETE | PARTIAL — list missing>
|
|
78
|
+
**Tie-break rules sufficient:** <YES | NO — name the gap>
|
|
79
|
+
**Required revisions (numbered, 1-3 max, only on ACCEPT_WITH_REVISIONS):**
|
|
80
|
+
1. <one sentence — smallest change>
|
|
81
|
+
2. <...>
|
|
82
|
+
3. <...>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
### Sandbox split quality
|
|
87
|
+
|
|
88
|
+
**Slim file preserves all RULE+LOGIC obligations:** <YES | NO — list lost>
|
|
89
|
+
**Mechanics file holds only mechanics+examples:** <YES | NO — list misplaced>
|
|
90
|
+
**Round-trip: rule_slim + load_context(mechanics) == original behaviour:**
|
|
91
|
+
<YES | NO — name the divergence>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
### Generalisability to remaining 8 rules
|
|
96
|
+
|
|
97
|
+
**Contract scales without per-rule tuning:** <YES | NO — name failure mode>
|
|
98
|
+
**Single biggest risk on the next rule (likely `non-destructive-by-default`):**
|
|
99
|
+
<one sentence>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
### Final verdict
|
|
104
|
+
|
|
105
|
+
**Lockable as-is for Phase 2A?** <YES | NO>
|
|
106
|
+
**If NO, single blocking change required:** <one sentence>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Verdict definitions:
|
|
110
|
+
- **ACCEPT** — contract ships unchanged; status moves to locked.
|
|
111
|
+
- **ACCEPT_WITH_REVISIONS** — locks after the 1-3 listed revisions land.
|
|
112
|
+
- **REJECT** — contract is structurally wrong; describe the fault.
|
|
113
|
+
|
|
114
|
+
The three artefacts follow this prompt verbatim.
|
|
115
|
+
"""
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def main() -> int:
|
|
119
|
+
anthropic = AnthropicClient(api_key=load_anthropic_key(), model="claude-sonnet-4-5")
|
|
120
|
+
openai = OpenAIClient(api_key=load_openai_key(), model="gpt-4o")
|
|
121
|
+
members = [anthropic, openai]
|
|
122
|
+
|
|
123
|
+
context = bundle_files(ARTEFACTS)
|
|
124
|
+
project = detect_project_context(REPO_ROOT)
|
|
125
|
+
table = load_prices()
|
|
126
|
+
|
|
127
|
+
user_prompt = REVIEW_PROMPT + "\n\n---\n\n" + context.text
|
|
128
|
+
|
|
129
|
+
question = CouncilQuestion(
|
|
130
|
+
mode="files",
|
|
131
|
+
user_prompt=user_prompt,
|
|
132
|
+
max_tokens=3072,
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
estimates = estimate(
|
|
136
|
+
question, members, table, project=project, original_ask=ORIGINAL_ASK,
|
|
137
|
+
)
|
|
138
|
+
print("=== ESTIMATE (single round, max tokens) ===")
|
|
139
|
+
total_est = 0.0
|
|
140
|
+
for c, e in zip(members, estimates):
|
|
141
|
+
print(f" {c.name}/{c.model}: ~{e.input_tokens} in + {e.output_tokens} out = ${e.total_usd:.4f}")
|
|
142
|
+
total_est += e.total_usd
|
|
143
|
+
print(f" TOTAL per round (max): ${total_est:.4f}")
|
|
144
|
+
print()
|
|
145
|
+
|
|
146
|
+
budget = CostBudget(
|
|
147
|
+
max_input_tokens=200_000,
|
|
148
|
+
max_output_tokens=80_000,
|
|
149
|
+
max_calls=20,
|
|
150
|
+
max_total_usd=2.50,
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
rounds_collected: list[list] = []
|
|
154
|
+
|
|
155
|
+
def _on_round_complete(round_idx: int, round_responses) -> None:
|
|
156
|
+
rounds_collected.append(list(round_responses))
|
|
157
|
+
print(f"=== ROUND {round_idx + 1} COMPLETE ===")
|
|
158
|
+
for r in round_responses:
|
|
159
|
+
if r.error:
|
|
160
|
+
print(f" [error] {r.provider}/{r.model}: {r.error}")
|
|
161
|
+
continue
|
|
162
|
+
actual = estimate_cost(r.provider, r.model, r.input_tokens, r.output_tokens, table)
|
|
163
|
+
print(f" [done] {r.provider}/{r.model}: {r.input_tokens} in / "
|
|
164
|
+
f"{r.output_tokens} out · {r.latency_ms} ms · ${actual.total_usd:.4f}")
|
|
165
|
+
print()
|
|
166
|
+
|
|
167
|
+
print("=== CONSULT (1 round, 2A.4 acceptance review) ===")
|
|
168
|
+
consult(
|
|
169
|
+
members, question, budget,
|
|
170
|
+
rounds=1,
|
|
171
|
+
on_round_complete=_on_round_complete,
|
|
172
|
+
table=table, project=project, original_ask=ORIGINAL_ASK,
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
if not rounds_collected:
|
|
176
|
+
print("[error] no rounds completed", file=sys.stderr)
|
|
177
|
+
return 1
|
|
178
|
+
|
|
179
|
+
actual_total = 0.0
|
|
180
|
+
for round_responses in rounds_collected:
|
|
181
|
+
for r in round_responses:
|
|
182
|
+
if r.error:
|
|
183
|
+
continue
|
|
184
|
+
actual = estimate_cost(r.provider, r.model, r.input_tokens, r.output_tokens, table)
|
|
185
|
+
actual_total += actual.total_usd
|
|
186
|
+
print(f"=== TOTAL ACTUAL: ${actual_total:.4f} ===")
|
|
187
|
+
|
|
188
|
+
final_round = rounds_collected[-1]
|
|
189
|
+
if not [r for r in final_round if not r.error]:
|
|
190
|
+
return 1
|
|
191
|
+
|
|
192
|
+
manifest = SessionManifest(
|
|
193
|
+
mode="files",
|
|
194
|
+
artefact="agents/roadmaps/structural-optimization-2A4-example.md",
|
|
195
|
+
original_ask=ORIGINAL_ASK,
|
|
196
|
+
members=[f"{r.provider}/{r.model}" for r in final_round],
|
|
197
|
+
rounds=len(rounds_collected),
|
|
198
|
+
cost_usd_estimated=total_est,
|
|
199
|
+
cost_usd_actual=actual_total,
|
|
200
|
+
extra={"purpose": "Council acceptance review of Phase 0.4 2A.4 worked example"},
|
|
201
|
+
)
|
|
202
|
+
session_dir = save_session(manifest=manifest, responses=rounds_collected)
|
|
203
|
+
print(f"[saved] {session_dir.relative_to(REPO_ROOT)}/")
|
|
204
|
+
return 1 if any(r.error for round_r in rounds_collected for r in round_r) else 0
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
if __name__ == "__main__":
|
|
208
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"""Council audit of Budget-v2 result (Phase 4.5 of road-to-context-layer-maturity).
|
|
2
|
+
|
|
3
|
+
Phase 4 of road-to-context-layer-maturity selected two 4d-trim paths
|
|
4
|
+
(`direct-answers`, `no-cheap-questions`) from a fixed option set
|
|
5
|
+
documented in agents/contexts/budget-v2-matrix.md and shipped them.
|
|
6
|
+
Exit-gate actuals (run 2026-05-04): total 44,928 / 49,000 chars
|
|
7
|
+
(91.7 %, 4,072 chars headroom) — ≥ 4,000 headroom goal hit. Top-3
|
|
8
|
+
sum unchanged. Safety-floor rules untouched.
|
|
9
|
+
|
|
10
|
+
Phase 4.5 requires a council audit before archival: confirm the
|
|
11
|
+
trim choices were sound, no semantic drift introduced, no better
|
|
12
|
+
path missed inside the Phase 4 inputs gate.
|
|
13
|
+
|
|
14
|
+
Invocation:
|
|
15
|
+
.venv/bin/python -m scripts.ai_council.one_off_archive.2026-05._one_off_budget_v2_audit
|
|
16
|
+
"""
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import sys
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
|
|
22
|
+
from scripts.ai_council.bundler import bundle_files
|
|
23
|
+
from scripts.ai_council.clients import (
|
|
24
|
+
AnthropicClient,
|
|
25
|
+
OpenAIClient,
|
|
26
|
+
load_anthropic_key,
|
|
27
|
+
load_openai_key,
|
|
28
|
+
)
|
|
29
|
+
from scripts.ai_council.orchestrator import (
|
|
30
|
+
CostBudget,
|
|
31
|
+
CouncilQuestion,
|
|
32
|
+
consult,
|
|
33
|
+
estimate,
|
|
34
|
+
)
|
|
35
|
+
from scripts.ai_council.pricing import estimate_cost, load_prices
|
|
36
|
+
from scripts.ai_council.project_context import detect_project_context
|
|
37
|
+
from scripts.ai_council.session import SessionManifest, save as save_session
|
|
38
|
+
|
|
39
|
+
REPO_ROOT = Path(__file__).resolve().parents[4]
|
|
40
|
+
ARTEFACTS = [
|
|
41
|
+
REPO_ROOT / "docs/contracts/load-context-budget-model.md",
|
|
42
|
+
REPO_ROOT / "agents/contexts/budget-v2-matrix.md",
|
|
43
|
+
REPO_ROOT / ".agent-src.uncompressed/rules/direct-answers.md",
|
|
44
|
+
REPO_ROOT / ".agent-src.uncompressed/rules/no-cheap-questions.md",
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
ORIGINAL_ASK = (
|
|
48
|
+
"Phase 4 of road-to-context-layer-maturity trimmed two always-rules "
|
|
49
|
+
"(direct-answers, no-cheap-questions) under the locked Model (b) "
|
|
50
|
+
"literal budget contract, hitting the ≥ 4,000-chars headroom goal "
|
|
51
|
+
"(actual: 4,072). Council task: audit the trim choices for "
|
|
52
|
+
"soundness and semantic drift before roadmap archival."
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
REVIEW_PROMPT = """\
|
|
56
|
+
# Council Audit — Budget-v2 Trim Result (Phase 4.5)
|
|
57
|
+
|
|
58
|
+
## Context
|
|
59
|
+
|
|
60
|
+
Phase 4 selected two 4d-trim paths from a fixed option set documented
|
|
61
|
+
in `budget-v2-matrix.md`. The matrix evaluated 4a (demote→auto), 4b
|
|
62
|
+
(merge), 4c (shared-context, locked at 3a Model (b) literal — no-op),
|
|
63
|
+
and 4d (compress prose) for every touchable always-rule. Safety-floor
|
|
64
|
+
rules (scope-control, non-destructive-by-default, commit-policy,
|
|
65
|
+
agent-authority) were untouchable. Outcome-untested rules were
|
|
66
|
+
restricted to 4d only per the Phase 4.0 inputs gate.
|
|
67
|
+
|
|
68
|
+
## Selected paths and result
|
|
69
|
+
|
|
70
|
+
- **4d on `direct-answers`** — emoji-scope subsection trimmed,
|
|
71
|
+
failure-mode collapsed to pointer. Δ ext: 4,098 → 3,987 (−111).
|
|
72
|
+
- **4d on `no-cheap-questions`** — "What counts as cheap" subsection
|
|
73
|
+
collapsed to pointer at `asking-and-brevity-examples.md`. Δ ext:
|
|
74
|
+
4,257 → 3,933 (−324).
|
|
75
|
+
|
|
76
|
+
Combined: −435 chars · headroom 3,637 → 4,072 (+435) · top-3 sum
|
|
77
|
+
unchanged · safety-floor rules untouched.
|
|
78
|
+
|
|
79
|
+
## Audit questions (please address each)
|
|
80
|
+
|
|
81
|
+
1. **Trim soundness** — do the surviving Iron Laws in both rules still
|
|
82
|
+
carry the rule's purpose, or did the prose trim sacrifice precision?
|
|
83
|
+
Cite the specific subsection if you find drift.
|
|
84
|
+
|
|
85
|
+
2. **Path selection** — was 4d the right choice for these two rules
|
|
86
|
+
given the matrix? Or should one of the deferred paths (4a, 4b)
|
|
87
|
+
have been picked despite the matrix verdict?
|
|
88
|
+
|
|
89
|
+
3. **Missed leverage** — inside the Phase 4 inputs gate (4d only on
|
|
90
|
+
outcome-untested rules; safety-floor untouchable), is there a
|
|
91
|
+
higher-leverage 4d target the matrix missed?
|
|
92
|
+
|
|
93
|
+
4. **Headroom durability** — 4,072 chars is +72 over the 4,000 goal.
|
|
94
|
+
Is this margin stable against expected near-term rule edits, or
|
|
95
|
+
should Phase 5 be tightened to defend it?
|
|
96
|
+
|
|
97
|
+
## Output Contract (STRICT)
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
### Verdict
|
|
101
|
+
**Trim choices sound:** <YES — archive · NO — escalate>
|
|
102
|
+
**One-sentence rationale:** <≤ 30 words>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
### Per-question findings (1–4 above)
|
|
107
|
+
1. <≤ 2 sentences>
|
|
108
|
+
2. <≤ 2 sentences>
|
|
109
|
+
3. <≤ 2 sentences>
|
|
110
|
+
4. <≤ 2 sentences>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
### Risk note
|
|
115
|
+
**Single biggest residual risk:** <one sentence>
|
|
116
|
+
**Mitigation (if any):** <one sentence or NONE>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Be decisive — total response ≤ 800 words. Artefacts follow verbatim.
|
|
120
|
+
"""
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def main() -> int:
|
|
124
|
+
anthropic = AnthropicClient(api_key=load_anthropic_key(), model="claude-sonnet-4-5")
|
|
125
|
+
openai = OpenAIClient(api_key=load_openai_key(), model="gpt-4o")
|
|
126
|
+
members = [anthropic, openai]
|
|
127
|
+
|
|
128
|
+
context = bundle_files(ARTEFACTS)
|
|
129
|
+
project = detect_project_context(REPO_ROOT)
|
|
130
|
+
table = load_prices()
|
|
131
|
+
|
|
132
|
+
user_prompt = REVIEW_PROMPT + "\n\n---\n\n" + context.text
|
|
133
|
+
|
|
134
|
+
question = CouncilQuestion(mode="files", user_prompt=user_prompt, max_tokens=2048)
|
|
135
|
+
|
|
136
|
+
estimates = estimate(question, members, table, project=project, original_ask=ORIGINAL_ASK)
|
|
137
|
+
print("=== ESTIMATE (single round) ===")
|
|
138
|
+
total_est = 0.0
|
|
139
|
+
for c, e in zip(members, estimates):
|
|
140
|
+
print(f" {c.name}/{c.model}: ~{e.input_tokens} in + {e.output_tokens} out = ${e.total_usd:.4f}")
|
|
141
|
+
total_est += e.total_usd
|
|
142
|
+
print(f" TOTAL per round (max): ${total_est:.4f}\n")
|
|
143
|
+
|
|
144
|
+
budget = CostBudget(
|
|
145
|
+
max_input_tokens=200_000,
|
|
146
|
+
max_output_tokens=80_000,
|
|
147
|
+
max_calls=20,
|
|
148
|
+
max_total_usd=2.50,
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
rounds_collected: list[list] = []
|
|
152
|
+
|
|
153
|
+
def _on_round_complete(round_idx: int, round_responses) -> None:
|
|
154
|
+
rounds_collected.append(list(round_responses))
|
|
155
|
+
print(f"=== ROUND {round_idx + 1} COMPLETE ===")
|
|
156
|
+
for r in round_responses:
|
|
157
|
+
if r.error:
|
|
158
|
+
print(f" [error] {r.provider}/{r.model}: {r.error}")
|
|
159
|
+
continue
|
|
160
|
+
actual = estimate_cost(r.provider, r.model, r.input_tokens, r.output_tokens, table)
|
|
161
|
+
print(f" [done] {r.provider}/{r.model}: {r.input_tokens} in / "
|
|
162
|
+
f"{r.output_tokens} out · {r.latency_ms} ms · ${actual.total_usd:.4f}")
|
|
163
|
+
print()
|
|
164
|
+
|
|
165
|
+
print("=== CONSULT (1 round, Phase 4.5 Budget-v2 audit) ===")
|
|
166
|
+
consult(
|
|
167
|
+
members, question, budget,
|
|
168
|
+
rounds=1,
|
|
169
|
+
on_round_complete=_on_round_complete,
|
|
170
|
+
table=table, project=project, original_ask=ORIGINAL_ASK,
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
if not rounds_collected:
|
|
174
|
+
print("[error] no rounds completed", file=sys.stderr)
|
|
175
|
+
return 1
|
|
176
|
+
|
|
177
|
+
actual_total = 0.0
|
|
178
|
+
for round_responses in rounds_collected:
|
|
179
|
+
for r in round_responses:
|
|
180
|
+
if r.error:
|
|
181
|
+
continue
|
|
182
|
+
actual = estimate_cost(r.provider, r.model, r.input_tokens, r.output_tokens, table)
|
|
183
|
+
actual_total += actual.total_usd
|
|
184
|
+
print(f"=== TOTAL ACTUAL: ${actual_total:.4f} ===")
|
|
185
|
+
|
|
186
|
+
final_round = rounds_collected[-1]
|
|
187
|
+
if not [r for r in final_round if not r.error]:
|
|
188
|
+
return 1
|
|
189
|
+
|
|
190
|
+
manifest = SessionManifest(
|
|
191
|
+
mode="files",
|
|
192
|
+
artefact="agents/roadmaps/road-to-context-layer-maturity.md",
|
|
193
|
+
original_ask=ORIGINAL_ASK,
|
|
194
|
+
members=[f"{r.provider}/{r.model}" for r in final_round],
|
|
195
|
+
rounds=len(rounds_collected),
|
|
196
|
+
cost_usd_estimated=total_est,
|
|
197
|
+
cost_usd_actual=actual_total,
|
|
198
|
+
extra={"purpose": "Phase 4.5 Budget-v2 trim-result audit"},
|
|
199
|
+
)
|
|
200
|
+
session_dir = save_session(manifest=manifest, responses=rounds_collected)
|
|
201
|
+
print(f"[saved] {session_dir.relative_to(REPO_ROOT)}/")
|
|
202
|
+
return 1 if any(r.error for round_r in rounds_collected for r in round_r) else 0
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
if __name__ == "__main__":
|
|
206
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""One-shot estimator for the v1 council review (no consult call).
|
|
2
|
+
|
|
3
|
+
Sibling of `_one_off_context_layer_v1_review.py`. Prints bundle size and
|
|
4
|
+
per-model token / cost projection so the user can confirm spend before
|
|
5
|
+
the actual consult fires.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
from scripts.ai_council._one_off_context_layer_v1_review import (
|
|
12
|
+
ORIGINAL_ASK,
|
|
13
|
+
REVIEW_PROMPT_HEADER,
|
|
14
|
+
ROADMAP_PATH,
|
|
15
|
+
_diff_stat,
|
|
16
|
+
_pr_body,
|
|
17
|
+
)
|
|
18
|
+
from scripts.ai_council.bundler import bundle_prompt
|
|
19
|
+
from scripts.ai_council.clients import (
|
|
20
|
+
AnthropicClient,
|
|
21
|
+
OpenAIClient,
|
|
22
|
+
load_anthropic_key,
|
|
23
|
+
load_openai_key,
|
|
24
|
+
)
|
|
25
|
+
from scripts.ai_council.orchestrator import CouncilQuestion, estimate
|
|
26
|
+
from scripts.ai_council.pricing import load_prices
|
|
27
|
+
from scripts.ai_council.project_context import detect_project_context
|
|
28
|
+
|
|
29
|
+
REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def main() -> int:
|
|
33
|
+
roadmap_text = ROADMAP_PATH.read_text(encoding="utf-8")
|
|
34
|
+
parts = [
|
|
35
|
+
REVIEW_PROMPT_HEADER,
|
|
36
|
+
"## PR #36 — diff --stat\n\n```\n" + _diff_stat() + "\n```",
|
|
37
|
+
"## PR #36 — body\n\n" + _pr_body(),
|
|
38
|
+
"## Roadmap v1\n\n" + roadmap_text,
|
|
39
|
+
]
|
|
40
|
+
bundle_text = "\n\n---\n\n".join(parts)
|
|
41
|
+
print(f"Bundle bytes: {len(bundle_text.encode('utf-8'))}")
|
|
42
|
+
|
|
43
|
+
ctx = bundle_prompt(bundle_text)
|
|
44
|
+
project = detect_project_context(REPO_ROOT)
|
|
45
|
+
table = load_prices()
|
|
46
|
+
|
|
47
|
+
anthropic = AnthropicClient(api_key=load_anthropic_key(), model="claude-sonnet-4-5")
|
|
48
|
+
openai = OpenAIClient(api_key=load_openai_key(), model="gpt-4o")
|
|
49
|
+
members = [anthropic, openai]
|
|
50
|
+
|
|
51
|
+
question = CouncilQuestion(mode="prompt", user_prompt=ctx.text, max_tokens=4096)
|
|
52
|
+
estimates = estimate(
|
|
53
|
+
question, members, table, project=project, original_ask=ORIGINAL_ASK,
|
|
54
|
+
)
|
|
55
|
+
total = 0.0
|
|
56
|
+
for c, e in zip(members, estimates):
|
|
57
|
+
print(
|
|
58
|
+
f" {c.name}/{c.model}: ~{e.input_tokens} in + "
|
|
59
|
+
f"{e.output_tokens} out = ${e.total_usd:.4f}"
|
|
60
|
+
)
|
|
61
|
+
total += e.total_usd
|
|
62
|
+
print(f" TOTAL (max, single round): ${total:.4f}")
|
|
63
|
+
return 0
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
if __name__ == "__main__":
|
|
67
|
+
raise SystemExit(main())
|