@event4u/agent-config 16.0.0 → 16.1.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 +297 -137
- package/CONTRIBUTING.md +9 -0
- package/README.md +2 -2
- package/dist/agent-src/commands/analyze/inbox.md +26 -0
- package/dist/agent-src/commands/analyze/roadmap-repos.md +27 -0
- package/dist/agent-src/commands/challenge-me/closure.md +178 -0
- package/dist/agent-src/commands/challenge-me.md +9 -2
- package/dist/agent-src/commands/council/default.md +25 -5
- package/dist/agent-src/commands/feature/plan.md +28 -1
- package/dist/agent-src/commands/feature/roadmap.md +28 -1
- package/dist/agent-src/commands/implement-ticket.md +27 -0
- package/dist/agent-src/commands/jira-ticket.md +27 -0
- package/dist/agent-src/commands/pr/create.md +29 -0
- package/dist/agent-src/commands/pr/merge.md +60 -9
- package/dist/agent-src/commands/roadmap/ai-council.md +7 -1
- package/dist/agent-src/commands/roadmap/create.md +74 -27
- package/dist/agent-src/commands/roadmap/materialize.md +27 -0
- package/dist/agent-src/commands/roadmap/process-full.md +123 -18
- package/dist/agent-src/commands/team.md +22 -0
- package/dist/agent-src/contexts/authority/scope-growth-ownership.md +80 -0
- package/dist/agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +47 -0
- package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +44 -3
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +15 -15
- package/dist/agent-src/contexts/execution/decision-closure-execution.md +93 -0
- package/dist/agent-src/contexts/execution/fix-loop-ladder.md +108 -0
- package/dist/agent-src/contexts/execution/plan-confidence-gate.md +4 -2
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +75 -6
- package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +57 -0
- package/dist/agent-src/guidelines/agent-infra/evaluator-independence-mechanics.md +102 -0
- package/dist/agent-src/guidelines/design-fidelity-routing.md +29 -0
- package/dist/agent-src/rules/autonomous-execution.md +15 -8
- package/dist/agent-src/rules/delegation-policy.md +23 -45
- package/dist/agent-src/rules/design-fidelity.md +32 -37
- package/dist/agent-src/rules/evaluator-independence.md +43 -49
- package/dist/agent-src/rules/test-first.md +41 -0
- package/dist/agent-src/skills/accessibility-auditor/data/manifest.json +3 -3
- package/dist/agent-src/skills/ai-council/SKILL.md +11 -3
- package/dist/agent-src/skills/api-design/data/manifest.json +3 -3
- package/dist/agent-src/skills/database/data/manifest.json +4 -4
- package/dist/agent-src/skills/database/data/query-tuning.csv +3 -3
- package/dist/agent-src/skills/design-review/SKILL.md +50 -0
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +14 -4
- package/dist/agent-src/skills/experiment-loop/SKILL.md +31 -1
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +1 -1
- package/dist/agent-src/skills/storybook-workshop/SKILL.md +42 -3
- package/dist/agent-src/skills/threat-modeling/SKILL.md +9 -4
- package/dist/agent-src/skills/threat-modeling/data/manifest.json +4 -4
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +37 -3
- package/dist/agent-src/templates/agent-settings.md +1 -1
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +188 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +62 -2
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +1 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +1 -0
- package/dist/cli-delegate/check_update_banner.js +40 -2
- package/dist/cli-delegate/chunk-4E2W63DA.js +335 -0
- package/dist/cli-delegate/chunk-5R7HOLAF.js +99 -0
- package/dist/cli-delegate/{chunk-IVBPRCQO.js → chunk-6KFEC3G7.js} +1 -1
- package/dist/cli-delegate/{chunk-2TAQ2K4V.js → chunk-6KM6ORRY.js} +55 -386
- package/dist/cli-delegate/{chunk-2XY7ILBT.js → chunk-FC75PGJE.js} +42 -2
- package/dist/cli-delegate/{chunk-GYC3VRYN.js → chunk-FXYUYU4N.js} +57 -13
- package/dist/cli-delegate/{chunk-55ACLDUE.js → chunk-GJCBB2UG.js} +168 -10
- package/dist/cli-delegate/{chunk-AK6HODNQ.js → chunk-HDVVGPQW.js} +873 -539
- package/dist/cli-delegate/{chunk-H32DGUJH.js → chunk-P6ZHP5W2.js} +1 -1
- package/dist/cli-delegate/{chunk-57PN4GYJ.js → chunk-RGNIWTEA.js} +1 -1
- package/dist/cli-delegate/chunk-ROYYTEZU.js +39 -0
- package/dist/cli-delegate/{chunk-3FKR64R5.js → chunk-UNCRJBT3.js} +31 -7
- package/dist/cli-delegate/{chunk-2DK2VJWG.js → chunk-WGXTVKCQ.js} +20 -6
- package/dist/cli-delegate/chunk-YDPILCOL.js +152 -0
- package/dist/cli-delegate/cmd_analyze_session.js +1 -1
- package/dist/cli-delegate/cmd_brand_status.js +1 -1
- package/dist/cli-delegate/cmd_conformance.js +90 -56
- package/dist/cli-delegate/cmd_doctor.js +7 -5
- package/dist/cli-delegate/cmd_explain.js +2 -2
- package/dist/cli-delegate/cmd_export.js +9 -7
- package/dist/cli-delegate/cmd_fleet.js +4 -2
- package/dist/cli-delegate/cmd_handoff.js +4 -4
- package/dist/cli-delegate/cmd_mcp_available.js +1 -1
- package/dist/cli-delegate/cmd_migrate.js +2 -2
- package/dist/cli-delegate/cmd_packs_active.js +2 -2
- package/dist/cli-delegate/cmd_preflight.js +4 -2
- package/dist/cli-delegate/cmd_prune.js +10 -8
- package/dist/cli-delegate/cmd_route_audit.js +2 -2
- package/dist/cli-delegate/cmd_route_explain.js +1 -1
- package/dist/cli-delegate/cmd_session_recycle.js +2 -2
- package/dist/cli-delegate/cmd_settings_get.js +28 -2
- package/dist/cli-delegate/cmd_settings_migrate.js +9 -7
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +10 -8
- package/dist/cli-delegate/cmd_uninstall.js +16 -13
- package/dist/cli-delegate/cmd_update.js +1 -1
- package/dist/cli-delegate/cmd_upgrade.js +1 -1
- package/dist/cli-delegate/cmd_validate.js +12 -10
- package/dist/cli-delegate/cmd_versions.js +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +85 -38
- 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 +10 -8
- package/dist/discovery/trust-report.md +3 -3
- package/dist/discovery/workspaces.json +8 -6
- package/dist/hooks/dispatch.js +1832 -1007
- package/dist/install/claudeRuleRewrite.js +14 -3
- package/dist/install/conflict.js +60 -10
- package/dist/install/conflictTracker.js +218 -0
- package/dist/install/fsPrimitives.js +54 -0
- package/dist/install/install.mjs +2007 -1481
- package/dist/install/manifestFiles.js +259 -0
- package/dist/install/preflight.js +14 -2
- package/dist/install/preserve.js +157 -0
- package/dist/install/recordedOwnership.js +132 -0
- package/dist/install/txlog.js +11 -2
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +398 -39
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/agent_settings.js +3 -2
- package/dist/scripts/_lib/fs_atomic.js +167 -0
- package/dist/scripts/_lib/installed_tools.js +460 -0
- package/dist/scripts/_lib/lean_projection_mode.js +3 -2
- package/dist/scripts/_lib/settings_renamed_keys.js +78 -0
- package/dist/server/routes/install.js +8 -0
- package/dist/server/routes/wizard.js +9 -3
- package/dist/server/schemas/settings.js +17 -5
- package/dist/shared/missionExecution.js +97 -0
- package/dist/ui/assets/{index-D0jaCRPM.js → index-DH1xc62v.js} +17 -17
- package/dist/ui/index.html +1 -1
- package/docs/MIGRATION.md +103 -0
- package/docs/contracts/settings-classes.md +26 -7
- package/docs/guidelines/agent-infra/active-remediation-mechanics.md +57 -0
- package/docs/guidelines/agent-infra/evaluator-independence-mechanics.md +102 -0
- package/docs/guidelines/design-fidelity-routing.md +29 -0
- package/package.json +1 -1
- package/src/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +62 -2
- package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +1 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +1 -0
- package/src/config/agent-settings.template.yml +139 -27
- package/src/config/auto-rule-budget.json +16 -0
- package/src/config/ci-local-parity.yml +18 -5
- package/src/config/continuity-surface.json +21 -0
- package/src/config/gate-coverage.yml +146 -13
- package/src/config/gate-violation-baselines.json +6 -6
- package/src/config/hook-token-budget.json +2 -0
- package/src/config/loop-surfaces.yaml +215 -0
- package/src/config/platform-anchor.json +3 -2
- package/src/config/release-gate-locality.yml +11 -0
- package/src/config/routing-coverage-seed.json +18 -4
- package/src/config/rule-enforcement-baseline.json +0 -1
- package/src/install/claudeRuleRewrite.ts +16 -2
- package/src/install/conflict.ts +65 -9
- package/src/install/conflictTracker.ts +299 -0
- package/src/install/fsPrimitives.ts +54 -0
- package/src/install/manifestFiles.ts +312 -0
- package/src/install/preflight.ts +16 -2
- package/src/install/preserve.ts +205 -0
- package/src/install/recordedOwnership.ts +149 -0
- package/src/install/txlog.ts +11 -2
- package/src/install/types.ts +19 -4
- package/src/scripts/_cli/cmd_conformance.ts +88 -15
- package/src/scripts/_cli/cmd_doctor.ts +4 -3
- package/src/scripts/_cli/cmd_route_explain.ts +9 -2
- package/src/scripts/_cli/cmd_settings_get.ts +44 -0
- package/src/scripts/_cli/doctor_execution.ts +90 -0
- package/src/scripts/_lib/activation_payload.ts +247 -0
- package/src/scripts/_lib/agent_settings.ts +4 -2
- package/src/scripts/_lib/authority_path.ts +102 -0
- package/src/scripts/_lib/cascade_base.ts +94 -0
- package/src/scripts/_lib/changelog_eras.ts +7 -2
- package/src/scripts/_lib/continuation_ladder.ts +149 -2
- package/src/scripts/_lib/council_transport.ts +129 -0
- package/src/scripts/_lib/delivery_ready.ts +112 -0
- package/src/scripts/_lib/forge_protection.ts +267 -0
- package/src/scripts/_lib/hook_platform_keys.ts +27 -0
- package/src/scripts/_lib/json_python_parity.ts +127 -0
- package/src/scripts/_lib/lean_projection_mode.ts +14 -3
- package/src/scripts/_lib/loop_surfaces.ts +382 -0
- package/src/scripts/_lib/mission_record.ts +190 -0
- package/src/scripts/_lib/obligation_frequency.ts +217 -0
- package/src/scripts/_lib/obligations.ts +402 -0
- package/src/scripts/_lib/orchestration_record.ts +11 -20
- package/src/scripts/_lib/release_highlights.ts +199 -10
- package/src/scripts/_lib/release_holds.ts +493 -0
- package/src/scripts/_lib/release_migration_gate.ts +184 -0
- package/src/scripts/_lib/rides_along.ts +102 -0
- package/src/scripts/_lib/settings_renamed_keys.ts +82 -0
- package/src/scripts/_lib/test_delta.ts +166 -0
- package/src/scripts/_lib/test_provenance.ts +171 -0
- package/src/scripts/_lib/typed_op_grant.ts +246 -0
- package/src/scripts/_lib/typed_op_watch.ts +185 -0
- package/src/scripts/ai_council/config.ts +8 -11
- package/src/scripts/ai_council/fallback_config.ts +5 -3
- package/src/scripts/ai_council/ownership_classes.ts +118 -0
- package/src/scripts/ask_block_census.ts +285 -15
- package/src/scripts/check_enforcement_matrix.ts +624 -0
- package/src/scripts/check_gate_reachability.ts +173 -10
- package/src/scripts/check_generator_sync.ts +954 -0
- package/src/scripts/check_preamble_payload_budget.ts +75 -2
- package/src/scripts/check_release_highlights.ts +33 -1
- package/src/scripts/check_release_holds.ts +567 -0
- package/src/scripts/check_rule_projection_integrity.ts +22 -12
- package/src/scripts/check_test_delta.ts +294 -0
- package/src/scripts/check_test_weakening.ts +299 -0
- package/src/scripts/closure_scan.ts +333 -0
- package/src/scripts/compile_hook_manifest.ts +43 -3
- package/src/scripts/council_record_shape.ts +209 -0
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +88 -9
- package/src/scripts/hooks/concern_registry.ts +4 -0
- package/src/scripts/hooks/design_pass_hook.ts +128 -3
- package/src/scripts/hooks/evidence_independence.ts +96 -0
- package/src/scripts/hooks/memory_recall_hook.ts +540 -0
- package/src/scripts/hooks/obligation_settle_hook.ts +182 -0
- package/src/scripts/hooks/rule_inject_hook.ts +49 -1
- package/src/scripts/hooks/run_continuation_hook.ts +17 -20
- package/src/scripts/hooks_doctor.ts +85 -0
- package/src/scripts/hooks_status.ts +19 -0
- package/src/scripts/install.ts +106 -206
- package/src/scripts/janitor.ts +7 -0
- package/src/scripts/lint_decision_classes.ts +464 -0
- package/src/scripts/lint_hook_manifest.ts +11 -0
- package/src/scripts/lint_major_migration_sections.ts +450 -0
- package/src/scripts/lint_plan_risk_register.ts +47 -3
- package/src/scripts/lint_roadmap_blockers.ts +61 -0
- package/src/scripts/lint_roadmap_producers.ts +202 -0
- package/src/scripts/measure_rule_budget.ts +101 -5
- package/src/scripts/new_roadmap.ts +37 -0
- package/src/scripts/orchestration_record.ts +0 -5
- package/src/scripts/release.ts +14 -98
- package/src/scripts/release_drill.ts +267 -1
- package/src/scripts/release_publication.ts +51 -0
- package/src/scripts/report_enforcement_drift.ts +566 -0
- package/src/scripts/report_host_injection_effect.ts +3 -11
- package/src/scripts/report_standing_payload_by_host.ts +26 -152
- package/src/scripts/schemas/agent-settings.schema.json +23 -0
- package/src/scripts/schemas/command.schema.json +4 -0
- package/src/scripts/scope_growth.ts +219 -0
- package/src/scripts/trigger_eval_grandfather.json +0 -1
- package/src/scripts/ui_conformance_probe.ts +622 -0
- package/src/server/schemas/settings.ts +31 -7
- package/src/shared/missionExecution.ts +126 -0
- package/dist/cli-delegate/chunk-523HCFYO.js +0 -90
|
@@ -36,6 +36,8 @@ const leanProjectionHost = z.enum(['claude-code', 'cursor', 'cline']);
|
|
|
36
36
|
const projectionMode = z.enum(['legacy-all', 'scoped']);
|
|
37
37
|
const memoryCadence = z.enum(['auto', 'always', 'never']);
|
|
38
38
|
const projectAudience = z.enum(['self', 'internal', 'client', 'public']);
|
|
39
|
+
const deliveryMerge = z.enum(['off', 'on-green']);
|
|
40
|
+
const prTopology = z.enum(['single', 'stacked']);
|
|
39
41
|
|
|
40
42
|
export const settingsSchema = z.object({
|
|
41
43
|
agent_config_version: z.string().default('').describe(
|
|
@@ -65,7 +67,7 @@ export const settingsSchema = z.object({
|
|
|
65
67
|
),
|
|
66
68
|
lean_projection: z.object({
|
|
67
69
|
mode: leanProjectionMode.default('eager-all').describe(
|
|
68
|
-
'How the per-tool projector emits the rule layer. eager-all = every rule body inlined into every projection (safe; what an ABSENT key still resolves to, per ADR-267 decision point 4). thin = kernel rules full-bodied + non-kernel rules as router-resolved pointers (~45k GPT-tok lighter per session), with no delivery mechanism. delivery = thin stubs PLUS the rule-inject hook concern, which delivers a body back on a trigger match; this is the value the SHIPPED TEMPLATE carries for Claude Code since ADR-267, and the
|
|
70
|
+
'How the per-tool projector emits the rule layer. eager-all = every rule body inlined into every projection (safe; what an ABSENT key still resolves to, per ADR-267 decision point 4). thin = kernel rules full-bodied + non-kernel rules as router-resolved pointers (~45k GPT-tok lighter per session, exact-BPE — a different unit from the chars/4 figures below, never compare the two directly), with no delivery mechanism. delivery = thin stubs PLUS the rule-inject hook concern, which delivers a body back on a trigger match; this is the value the SHIPPED TEMPLATE carries for Claude Code since ADR-267. SAVING AND CHARGE, MEASURED TOGETHER so neither is published alone (2026-09-12, `check_preamble_payload_budget`): the rule bucket falls 122,769 -> 24,537 chars/4 tok per session on a thinned host (-80.0%), and a trigger match costs p50 6,728 B / p90 14,016 B / max 16,297 B per fire over 318 gate-open fires of the frozen tests/eval/routing-matrix corpus at the concern\'s 16,384 B cap. Bytes per fire and tokens per session are different denominators and are never summed; re-read both rather than quoting this line. The ceiling for that charge is registered in src/config/hook-token-budget.json (user_prompt_submit slot sum 4,096 -> 16,384).',
|
|
69
71
|
),
|
|
70
72
|
hosts: z.array(leanProjectionHost).default(['claude-code']).describe(
|
|
71
73
|
'Which hosts a thinning mode may thin (ADR-267). Absent resolves to [claude-code]. '
|
|
@@ -161,6 +163,17 @@ export const settingsSchema = z.object({
|
|
|
161
163
|
'How the agent replies to PR review comments. create_review_comment = post a new review comment (works on every GitHub plan). replies_endpoint = thread the reply under the original comment (needs the newer REST endpoint). auto = detect at runtime, prefer threaded replies when available.',
|
|
162
164
|
),
|
|
163
165
|
}),
|
|
166
|
+
delivery: z.object({
|
|
167
|
+
merge: deliveryMerge.default('off').describe(
|
|
168
|
+
'Whether a run may merge the pull request it produced. off (default) = the run ends at mergeable-green-and-open and says so. on-green = merge is permitted, and only when an object-bound grant covering {op: prod_merge, target: <base>} exists and the final head is required-check-green, target-current and tamper-checked. This key is a precondition, never the authorisation by itself; forge auto-merge is the mechanism, so branch protection stays the gate.',
|
|
169
|
+
),
|
|
170
|
+
wait_for_ci: z.boolean().default(true).describe(
|
|
171
|
+
'Whether the run stays alive until the required checks settle. true (default) = the run drives CI and reports the settled verdict. false = the run ends once the branch is pushed and the PR is open, leaving the checks to be read later. Independent of merge: a run may wait for CI without being allowed to merge.',
|
|
172
|
+
),
|
|
173
|
+
pr_topology: prTopology.default('single').describe(
|
|
174
|
+
'How a mission\'s work is shaped into pull requests. single (default) = one branch, one pull request. stacked = a dependent series. stacked is never chosen by the agent and never asked about at roadmap creation — the owner plans it or it does not happen.',
|
|
175
|
+
),
|
|
176
|
+
}),
|
|
164
177
|
augment: z.object({
|
|
165
178
|
rules_use_symlinks: z.boolean().default(false).describe(
|
|
166
179
|
'When true, .augment/rules/*.md are symlinks into dist/agent-src/rules/ — edits flow back to source on save. When false (default), they are copies — safer on Windows and shared volumes, but rule edits in .augment/ are lost on the next `task sync`.',
|
|
@@ -202,8 +215,8 @@ export const settingsSchema = z.object({
|
|
|
202
215
|
skip_pre_run_gate: z.boolean().default(true).describe(
|
|
203
216
|
'Skip the /roadmap:process-* pre-run confirmation gate. true (default) starts processing immediately and surfaces the resolved config inline; false shows the numbered-options gate and waits. A genuine "which roadmap?" ambiguity always prompts regardless.',
|
|
204
217
|
),
|
|
205
|
-
quality_cadence: qualityCadence.default('
|
|
206
|
-
'When the agent runs the full quality / test suite during /roadmap:process-* runs.
|
|
218
|
+
quality_cadence: qualityCadence.default('per_phase').describe(
|
|
219
|
+
'When the agent runs the full quality / test suite during /roadmap:process-* runs. per_phase = after each phase boundary (default since 2026-09-13 — end_of_roadmap lets errors compound across phases, which is expensive in a multi-phase autonomous run nobody is watching). end_of_roadmap = once, after the last step (fastest). per_step = after every single step (slowest, highest confidence).',
|
|
207
220
|
),
|
|
208
221
|
dashboard_regen_cadence: regenCadence.default('every_5_steps').describe(
|
|
209
222
|
'How often the agent regenerates agents/roadmaps/dashboard.md during a roadmap run. every_5_steps = batch the regen (default). per_step = after every step (freshest dashboard, highest subprocess overhead). phase_boundary = only at phase edges. A rename, phase add, or archive always regenerates immediately regardless.',
|
|
@@ -221,8 +234,8 @@ export const settingsSchema = z.object({
|
|
|
221
234
|
}).default({ max_cost_per_run_usd: 5, max_cost_per_rolling_7d_usd: 25 }),
|
|
222
235
|
}),
|
|
223
236
|
planning: z.object({
|
|
224
|
-
|
|
225
|
-
'Gate C — plan-
|
|
237
|
+
closure_pass: z.boolean().default(true).describe(
|
|
238
|
+
'Gate C — plan-closure pass. true (default) = a plan-artifact ask (/roadmap:create, roadmap-writing, /feature:plan, /feature:roadmap, /roadmap:materialize, /implement-ticket, /jira-ticket, /analyze:inbox, /analyze:roadmap-repos) ends in a closure pass (/challenge-me closure): every foreseeable decision is closed at the lowest rung that owns it and written into the roadmap\'s "## Decisions" table, so a long run never meets a question planning could have closed. false = inert, plan asks author directly. An explicit user bypass always wins for that turn and is counted as a bypass rather than as an absent closure.',
|
|
226
239
|
),
|
|
227
240
|
risk_review: z.boolean().default(true).describe(
|
|
228
241
|
'Gate R1 — plan-risk review. true (default) = every ready (non-draft) plan must carry a schema-valid "## Risk Register" section (ranked risks, mitigation + anchor per row, freshness marker, exact honest-null grammar), enforced by lint_plan_risk_register at pre-push + CI. false = escape hatch, the validator skips.',
|
|
@@ -238,9 +251,20 @@ export const settingsSchema = z.object({
|
|
|
238
251
|
// test whose fixture predates the section. With the default, an absent
|
|
239
252
|
// section materialises as the three `true` leaves the contract promises.
|
|
240
253
|
.default({}),
|
|
254
|
+
execution: z.object({
|
|
255
|
+
fix_loop_max: z.number().int().min(1).default(10).describe(
|
|
256
|
+
'Consecutive failed fix attempts against one validation target before the escalation ladder reaches its terminal rung. Reaching the bound triggers a strategy change, never a question. Overridable globally, per project and per prompt.',
|
|
257
|
+
),
|
|
258
|
+
escalation: z.array(z.string()).default(['independent', 'council', 'team', 'owner_owned_check']).describe(
|
|
259
|
+
'The escalation rungs, in order, walked when the fix-loop bound is reached: independent (another session or a provider-diverse reviewer), council, team, then owner_owned_check — which asks whether the residue is owner-owned, not whether to ask the owner now.',
|
|
260
|
+
),
|
|
261
|
+
}).default({}),
|
|
241
262
|
quality: z.object({
|
|
242
263
|
local_auto_run: z.boolean().default(false).describe(
|
|
243
|
-
'Run quality tools (linters, type-checks, formatters) and the local test suite autonomously after edits. Off by default —
|
|
264
|
+
'Run quality tools (linters, type-checks, formatters) and the local test suite autonomously after edits, IN CHAT. Off by default — in a chat turn a human is present and remote CI is the authoritative gate, so a local full-pipeline run duplicates it at wall-clock cost. The agent only runs a quality tool on an explicit ask, a concrete CI failure, or the new-gate carve-out. A mission is governed by local_auto_run_in_mission instead.',
|
|
265
|
+
),
|
|
266
|
+
local_auto_run_in_mission: z.boolean().default(true).describe(
|
|
267
|
+
'Run quality tools autonomously inside a mission — an autonomous roadmap run with a claimed contract. On by default: nobody is waiting, the next action belongs to the agent itself, and a red found twenty steps later costs more than the run that would have caught it at step one. Inert outside a mission, and a mission never lowers local_auto_run: true.',
|
|
244
268
|
),
|
|
245
269
|
}),
|
|
246
270
|
design: z.object({
|
|
@@ -547,7 +571,7 @@ export const settingsSchema = z.object({
|
|
|
547
571
|
}).default({}),
|
|
548
572
|
rtk_wrap: z.object({
|
|
549
573
|
enabled: z.boolean().default(false).describe(
|
|
550
|
-
'PreToolUse RTK-wrap nudge (token-saving Phase 3). Default off. When on AND the binary on PATH is verified as Rust Token Killer (a live two-stage identity probe — not a self-reported flag, and never a colliding same-name binary), warns (never blocks) "re-run wrapped with rtk" before a single verbose CLI command (git/npm/cargo/docker/…) — upstream reports 60–90% output-token savings (their estimate). Skips completeness-critical / piped / compound commands and git diff. No-op when rtk is absent, unverified, or a different tool.',
|
|
574
|
+
'PreToolUse RTK-wrap nudge (token-saving Phase 3). Default off. When on AND the binary on PATH is verified as Rust Token Killer (a live two-stage identity probe — not a self-reported flag, and never a colliding same-name binary), warns (never blocks) "re-run wrapped with rtk" before a single verbose CLI command (git/npm/cargo/docker/…) — upstream reports 60–90% output-token savings (their estimate). Skips completeness-critical / piped / compound commands and git diff. No-op when rtk is absent, unverified, or a different tool. Its own activation charge is one advisory line under the 1,024 B default concern cap in src/config/hook-token-budget.json; the per-fire distribution is UNMEASURED — stated rather than estimated, because the saving above is a third-party output-token claim and not a standing-payload reduction this package measured.',
|
|
551
575
|
),
|
|
552
576
|
}).default({}),
|
|
553
577
|
design_slop: z.object({
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mission execution posture — the loop bound, its escalation ladder, and the
|
|
3
|
+
* one setting whose value differs inside a mission.
|
|
4
|
+
*
|
|
5
|
+
* `road-to-adversarial-verification-and-long-runs` Phase 0. Three facts that
|
|
6
|
+
* were previously either absent or stated only in prose get one module, because
|
|
7
|
+
* all three are read by more than one surface (`doctor --json`, `settings:get`,
|
|
8
|
+
* the recovery ladder) and a constant restated per reader is the standard way a
|
|
9
|
+
* default drifts.
|
|
10
|
+
*
|
|
11
|
+
* **Why a mission changes `quality.local_auto_run` and nothing else does.** The
|
|
12
|
+
* template's own justification for shipping `false` is that remote CI is the
|
|
13
|
+
* authoritative gate and a local full-pipeline run duplicates it at wall-clock
|
|
14
|
+
* cost. That argument is about a CHAT turn, where the human is present, the next
|
|
15
|
+
* action is theirs, and the pipeline's result arrives long after the reply. It is
|
|
16
|
+
* not an argument about an autonomous mission, where nobody is waiting, the next
|
|
17
|
+
* action is the agent's own, and a red found after twenty more steps costs more
|
|
18
|
+
* than the pipeline run that would have found it at step one. The roadmap
|
|
19
|
+
* template already says as much about the sibling cadence knob — that
|
|
20
|
+
* `end_of_roadmap` lets errors compound across phases — so the two knobs are
|
|
21
|
+
* corrected together rather than one at a time.
|
|
22
|
+
*
|
|
23
|
+
* The resolution is deliberately NOT a settings-layer precedence trick. A layer
|
|
24
|
+
* is a place a human wrote a value; a mission is a runtime condition. Folding
|
|
25
|
+
* the condition into the layer stack would make `settings:get` report a source
|
|
26
|
+
* file for a value no file contains.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/** The escalation rungs, in the order the recovery ladder walks them. */
|
|
30
|
+
export const ESCALATION_LADDER: readonly string[] = [
|
|
31
|
+
'independent',
|
|
32
|
+
'council',
|
|
33
|
+
'team',
|
|
34
|
+
'owner_owned_check',
|
|
35
|
+
] as const;
|
|
36
|
+
|
|
37
|
+
/** Default bound on consecutive failed fix attempts against one target. */
|
|
38
|
+
export const FIX_LOOP_MAX_DEFAULT = 10;
|
|
39
|
+
|
|
40
|
+
/** Default for `quality.local_auto_run_in_mission`. */
|
|
41
|
+
export const MISSION_AUTO_RUN_DEFAULT = true;
|
|
42
|
+
|
|
43
|
+
/** Where a resolved `quality.local_auto_run` value came from. */
|
|
44
|
+
export type AutoRunOrigin = 'mission' | 'settings';
|
|
45
|
+
|
|
46
|
+
export interface AutoRunResolution {
|
|
47
|
+
/** The value a reader should act on. */
|
|
48
|
+
readonly value: boolean;
|
|
49
|
+
/** `mission` when the mission condition decided, `settings` otherwise. */
|
|
50
|
+
readonly origin: AutoRunOrigin;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface AutoRunInputs {
|
|
54
|
+
/** `quality.local_auto_run` as the settings layers resolved it. */
|
|
55
|
+
readonly configured: boolean;
|
|
56
|
+
/** `quality.local_auto_run_in_mission`, or `undefined` for the default. */
|
|
57
|
+
readonly missionValue?: boolean | undefined;
|
|
58
|
+
/** True only inside an autonomous mission (a claimed roadmap run). */
|
|
59
|
+
readonly inMission: boolean;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Resolve `quality.local_auto_run` for the current run.
|
|
64
|
+
*
|
|
65
|
+
* Outside a mission the configured value wins unchanged — that is the whole
|
|
66
|
+
* point of leaving chat alone. Inside one, `local_auto_run_in_mission` decides.
|
|
67
|
+
*
|
|
68
|
+
* One asymmetry is deliberate: a mission never LOWERS the configured value. An
|
|
69
|
+
* operator who set `local_auto_run: true` asked for pipeline runs everywhere,
|
|
70
|
+
* and a mission is not a reason to give them fewer.
|
|
71
|
+
*/
|
|
72
|
+
export function resolveLocalAutoRun(inputs: AutoRunInputs): AutoRunResolution {
|
|
73
|
+
if (inputs.configured) return { value: true, origin: 'settings' };
|
|
74
|
+
if (!inputs.inMission) return { value: false, origin: 'settings' };
|
|
75
|
+
const mission = inputs.missionValue ?? MISSION_AUTO_RUN_DEFAULT;
|
|
76
|
+
return mission ? { value: true, origin: 'mission' } : { value: false, origin: 'settings' };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Fold `execution.*` out of a settings-override stream, last layer wins.
|
|
81
|
+
*
|
|
82
|
+
* Takes the same `[dotted, value, file]` tuples `iter_setting_overrides` emits,
|
|
83
|
+
* so a caller never re-implements the cascade. Keys outside the `execution.`
|
|
84
|
+
* prefix are ignored rather than collected: this is a narrow reader, and a
|
|
85
|
+
* reader that accidentally carries the whole settings tree is how a doctor
|
|
86
|
+
* payload grows a field nobody declared.
|
|
87
|
+
*/
|
|
88
|
+
export function executionPostureFromOverrides(
|
|
89
|
+
layers: Iterable<readonly [string, unknown, string]>,
|
|
90
|
+
): ExecutionPosture {
|
|
91
|
+
const raw: Record<string, unknown> = {};
|
|
92
|
+
for (const [key, value] of layers) {
|
|
93
|
+
if (key === 'execution.fix_loop_max') raw['fix_loop_max'] = value;
|
|
94
|
+
else if (key === 'execution.escalation') raw['escalation'] = value;
|
|
95
|
+
}
|
|
96
|
+
return resolveExecutionPosture(raw);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface ExecutionPosture {
|
|
100
|
+
readonly fix_loop_max: number;
|
|
101
|
+
readonly escalation: readonly string[];
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* The `execution:` block as a reader should see it, defaults filled in.
|
|
106
|
+
*
|
|
107
|
+
* A non-integer, non-positive or absent `fix_loop_max` falls back to the default
|
|
108
|
+
* rather than propagating: a bound of `0` would make every first attempt
|
|
109
|
+
* terminal, which is a configuration that can only be a mistake.
|
|
110
|
+
*/
|
|
111
|
+
export function resolveExecutionPosture(raw: unknown): ExecutionPosture {
|
|
112
|
+
const block = (raw ?? {}) as Record<string, unknown>;
|
|
113
|
+
const rawMax = block['fix_loop_max'];
|
|
114
|
+
const max =
|
|
115
|
+
typeof rawMax === 'number' && Number.isInteger(rawMax) && rawMax > 0
|
|
116
|
+
? rawMax
|
|
117
|
+
: FIX_LOOP_MAX_DEFAULT;
|
|
118
|
+
const rawLadder = block['escalation'];
|
|
119
|
+
const ladder =
|
|
120
|
+
Array.isArray(rawLadder) &&
|
|
121
|
+
rawLadder.length > 0 &&
|
|
122
|
+
rawLadder.every((r) => typeof r === 'string')
|
|
123
|
+
? (rawLadder as string[])
|
|
124
|
+
: ESCALATION_LADDER;
|
|
125
|
+
return { fix_loop_max: max, escalation: ladder };
|
|
126
|
+
}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);
|
|
2
|
-
|
|
3
|
-
// src/install/plan.ts
|
|
4
|
-
import { createHash } from "node:crypto";
|
|
5
|
-
import { readFileSync, readdirSync, statSync } from "node:fs";
|
|
6
|
-
import { join, relative, resolve } from "node:path";
|
|
7
|
-
function sha256File(path) {
|
|
8
|
-
try {
|
|
9
|
-
const data = readFileSync(path);
|
|
10
|
-
return createHash("sha256").update(data).digest("hex");
|
|
11
|
-
} catch {
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
function fileEntry(path, kind, options) {
|
|
16
|
-
return {
|
|
17
|
-
path,
|
|
18
|
-
kind,
|
|
19
|
-
sha256: options.hashContent ? sha256File(path) : null
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
function walkSourceTree(dir) {
|
|
23
|
-
const out = [];
|
|
24
|
-
walkInto(dir, out);
|
|
25
|
-
return out;
|
|
26
|
-
}
|
|
27
|
-
function walkInto(dir, out) {
|
|
28
|
-
let entries;
|
|
29
|
-
try {
|
|
30
|
-
entries = readdirSync(dir).sort();
|
|
31
|
-
} catch {
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
for (const name of entries) {
|
|
35
|
-
const full = join(dir, name);
|
|
36
|
-
let isDir;
|
|
37
|
-
try {
|
|
38
|
-
isDir = statSync(full).isDirectory();
|
|
39
|
-
} catch {
|
|
40
|
-
continue;
|
|
41
|
-
}
|
|
42
|
-
if (isDir) {
|
|
43
|
-
walkInto(full, out);
|
|
44
|
-
} else {
|
|
45
|
-
out.push(full);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
function buildInstallPlan(inputs) {
|
|
50
|
-
const filesByTool = {};
|
|
51
|
-
for (const source of inputs.sources) {
|
|
52
|
-
const bucket = filesByTool[source.toolId] ?? [];
|
|
53
|
-
let files = walkSourceTree(source.srcDir);
|
|
54
|
-
if (source.fileFilter !== void 0) {
|
|
55
|
-
files = files.filter(source.fileFilter);
|
|
56
|
-
}
|
|
57
|
-
for (const srcFile of files) {
|
|
58
|
-
const rel = relative(source.srcDir, srcFile);
|
|
59
|
-
const destPath = resolve(source.destDir, rel);
|
|
60
|
-
bucket.push(
|
|
61
|
-
fileEntry(srcFile, source.kind, {
|
|
62
|
-
hashContent: source.kind !== "bridge"
|
|
63
|
-
})
|
|
64
|
-
);
|
|
65
|
-
bucket[bucket.length - 1] = {
|
|
66
|
-
...bucket[bucket.length - 1],
|
|
67
|
-
path: destPath
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
filesByTool[source.toolId] = bucket;
|
|
71
|
-
}
|
|
72
|
-
for (const source of inputs.sources) {
|
|
73
|
-
if (!(source.toolId in filesByTool)) {
|
|
74
|
-
filesByTool[source.toolId] = [];
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return {
|
|
78
|
-
version: 2,
|
|
79
|
-
target: inputs.target,
|
|
80
|
-
root: inputs.root,
|
|
81
|
-
filesByTool,
|
|
82
|
-
mergedKeysByTool: {},
|
|
83
|
-
policy: inputs.policy
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export {
|
|
88
|
-
sha256File,
|
|
89
|
-
buildInstallPlan
|
|
90
|
-
};
|