@event4u/agent-config 8.9.0 → 8.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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +189 -0
- package/README.md +5 -5
- package/dist/agent-src/commands/challenge-me/vision.md +121 -32
- package/dist/agent-src/commands/challenge-me/with-docs.md +21 -8
- package/dist/agent-src/commands/commit/in-chunks.md +1 -1
- package/dist/agent-src/commands/commit.md +2 -1
- package/dist/agent-src/commands/cost/report.md +14 -3
- package/dist/agent-src/commands/feature/dev.md +4 -4
- package/dist/agent-src/commands/humanize.md +101 -0
- package/dist/agent-src/commands/jira-ticket.md +2 -2
- package/dist/agent-src/commands/memory/load.md +15 -0
- package/dist/agent-src/commands/optimize/project.md +12 -0
- package/dist/agent-src/commands/roadmap/create.md +12 -11
- package/dist/agent-src/commands/tests/create.md +29 -7
- package/dist/agent-src/commands/work.md +33 -0
- package/dist/agent-src/commands/worktree/cleanup.md +83 -0
- package/dist/agent-src/commands/worktree/create.md +64 -0
- package/dist/agent-src/commands/worktree/status.md +75 -0
- package/dist/agent-src/commands/worktree/verify.md +70 -0
- package/dist/agent-src/commands/worktree.md +85 -0
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +66 -0
- package/dist/agent-src/contexts/execution/orchestration-benchmark-gate.md +1 -0
- package/dist/agent-src/contexts/execution/orchestration-telemetry.md +91 -34
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +14 -0
- package/dist/agent-src/contexts/execution/roadmap-writing-source-derived.md +65 -0
- package/dist/agent-src/contexts/execution/subagent-modes-detail.md +84 -0
- package/dist/agent-src/rules/autonomous-execution.md +7 -37
- package/dist/agent-src/rules/broken-access-control.md +7 -45
- package/dist/agent-src/rules/code-comment-discipline.md +148 -0
- package/dist/agent-src/rules/context-hygiene.md +14 -0
- package/dist/agent-src/rules/delegation-policy.md +10 -8
- package/dist/agent-src/rules/design-fidelity.md +44 -0
- package/dist/agent-src/rules/git-history-discipline.md +4 -79
- package/dist/agent-src/rules/legal-safety-floor.md +11 -55
- package/dist/agent-src/rules/roadmap-progress-sync.md +5 -56
- package/dist/agent-src/rules/spreadsheet-source-quality.md +61 -0
- package/dist/agent-src/rules/think-before-action.md +10 -0
- package/dist/agent-src/rules/verify-before-complete.md +12 -0
- package/dist/agent-src/skills/accessibility-auditor/evals/evals.json +15 -0
- package/dist/agent-src/skills/agent-docs-writing/SKILL.md +13 -12
- package/dist/agent-src/skills/ai-council/SKILL.md +19 -9
- package/dist/agent-src/skills/analysis-skill-router/evals/evals.json +13 -0
- package/dist/agent-src/skills/api-design/SKILL.md +7 -5
- package/dist/agent-src/skills/api-testing/SKILL.md +16 -2
- package/dist/agent-src/skills/authz-review/SKILL.md +59 -2
- package/dist/agent-src/skills/blast-radius-analyzer/SKILL.md +1 -1
- package/dist/agent-src/skills/bug-analyzer/SKILL.md +19 -16
- package/dist/agent-src/skills/character-consistency/evals/evals.json +16 -0
- package/dist/agent-src/skills/code-refactoring/SKILL.md +9 -9
- package/dist/agent-src/skills/command-routing/evals/evals.json +14 -0
- package/dist/agent-src/skills/content-funnel-design/SKILL.md +2 -0
- package/dist/agent-src/skills/dashboard-design/evals/evals.json +16 -0
- package/dist/agent-src/skills/data-flow-mapper/SKILL.md +1 -1
- package/dist/agent-src/skills/dcf-modeling/evals/evals.json +20 -0
- package/dist/agent-src/skills/decision-record/evals/evals.json +20 -0
- package/dist/agent-src/skills/defense-in-depth/SKILL.md +2 -2
- package/dist/agent-src/skills/dependency-upgrade/SKILL.md +7 -7
- package/dist/agent-src/skills/design-intelligence/SKILL.md +8 -8
- package/dist/agent-src/skills/design-intelligence/evals/evals.json +14 -0
- package/dist/agent-src/skills/design-review/SKILL.md +29 -2
- package/dist/agent-src/skills/design-system-capture/SKILL.md +21 -0
- package/dist/agent-src/skills/design-system-capture/evals/evals.json +15 -0
- package/dist/agent-src/skills/developer-like-execution/evals/evals.json +16 -0
- package/dist/agent-src/skills/doc-coauthoring/SKILL.md +29 -0
- package/dist/agent-src/skills/doc-coauthoring/evals/evals.json +16 -0
- package/dist/agent-src/skills/editorial-calendar/SKILL.md +2 -0
- package/dist/agent-src/skills/editorial-calendar/evals/domain-truth.json +16 -0
- package/dist/agent-src/skills/editorial-calendar/evals/evals.json +16 -0
- package/dist/agent-src/skills/estimate-ticket/evals/evals.json +16 -0
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +30 -0
- package/dist/agent-src/skills/existing-ui-audit/evals/triggers.json +47 -0
- package/dist/agent-src/skills/fe-design/SKILL.md +43 -14
- package/dist/agent-src/skills/fe-design/evals/triggers.json +47 -0
- package/dist/agent-src/skills/forecasting/evals/evals.json +20 -0
- package/dist/agent-src/skills/fundraising-narrative/evals/domain-truth.json +16 -0
- package/dist/agent-src/skills/fundraising-narrative/evals/evals.json +16 -0
- package/dist/agent-src/skills/git-workflow/SKILL.md +86 -0
- package/dist/agent-src/skills/html-deck/SKILL.md +27 -0
- package/dist/agent-src/skills/humanizer/SKILL.md +147 -0
- package/dist/agent-src/skills/humanizer/data/patterns.md +190 -0
- package/dist/agent-src/skills/humanizer/evals/triggers.json +17 -0
- package/dist/agent-src/skills/iconography/SKILL.md +24 -0
- package/dist/agent-src/skills/incident-commander/evals/domain-truth.json +16 -0
- package/dist/agent-src/skills/incident-commander/evals/evals.json +20 -0
- package/dist/agent-src/skills/laravel/SKILL.md +14 -1
- package/dist/agent-src/skills/launch-readiness/SKILL.md +20 -19
- package/dist/agent-src/skills/launch-readiness/evals/evals.json +21 -0
- package/dist/agent-src/skills/legal-practice-profile/SKILL.md +126 -0
- package/dist/agent-src/skills/logging-monitoring/SKILL.md +1 -1
- package/dist/agent-src/skills/logging-monitoring/evals/evals.json +16 -0
- package/dist/agent-src/skills/mcp/SKILL.md +1 -1
- package/dist/agent-src/skills/memory-consolidation/SKILL.md +14 -1
- package/dist/agent-src/skills/messaging-architecture/evals/domain-truth.json +16 -0
- package/dist/agent-src/skills/messaging-architecture/evals/evals.json +16 -0
- package/dist/agent-src/skills/migration-architect/SKILL.md +2 -1
- package/dist/agent-src/skills/perf-feedback-craft/evals/evals.json +16 -0
- package/dist/agent-src/skills/performance/SKILL.md +1 -1
- package/dist/agent-src/skills/pest-testing/SKILL.md +1 -1
- package/dist/agent-src/skills/php-debugging/SKILL.md +17 -0
- package/dist/agent-src/skills/playwright-testing/SKILL.md +16 -0
- package/dist/agent-src/skills/prompt-engineering-patterns/evals/evals.json +16 -0
- package/dist/agent-src/skills/readme-writing/SKILL.md +2 -0
- package/dist/agent-src/skills/readme-writing-package/SKILL.md +2 -0
- package/dist/agent-src/skills/refine-prompt/evals/evals.json +16 -0
- package/dist/agent-src/skills/refine-ticket/evals/evals.json +16 -0
- package/dist/agent-src/skills/release-comms/SKILL.md +2 -0
- package/dist/agent-src/skills/release-comms/evals/evals.json +16 -0
- package/dist/agent-src/skills/rice-prioritization/evals/evals.json +20 -0
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +22 -51
- package/dist/agent-src/skills/runway-cognition/evals/evals.json +20 -0
- package/dist/agent-src/skills/scenario-modeling/evals/evals.json +20 -0
- package/dist/agent-src/skills/security-audit/SKILL.md +6 -9
- package/dist/agent-src/skills/sentry-integration/SKILL.md +2 -2
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +8 -0
- package/dist/agent-src/skills/source-discovery/SKILL.md +26 -24
- package/dist/agent-src/skills/spreadsheet-authoring/SKILL.md +98 -0
- package/dist/agent-src/skills/spreadsheet-authoring/evals/triggers.json +47 -0
- package/dist/agent-src/skills/subagent-orchestration/SKILL.md +55 -46
- package/dist/agent-src/skills/subagent-orchestration/evals/evals.json +42 -0
- package/dist/agent-src/skills/systematic-debugging/SKILL.md +10 -0
- package/dist/agent-src/skills/systematic-debugging/evals/evals.json +20 -0
- package/dist/agent-src/skills/test-case-discovery/SKILL.md +118 -0
- package/dist/agent-src/skills/test-case-discovery/evals/triggers.json +52 -0
- package/dist/agent-src/skills/test-driven-development/SKILL.md +32 -6
- package/dist/agent-src/skills/test-driven-development/evals/evals.json +16 -0
- package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +7 -6
- package/dist/agent-src/skills/threat-modeling/evals/evals.json +21 -0
- package/dist/agent-src/skills/typography-system/evals/evals.json +14 -0
- package/dist/agent-src/skills/unit-economics-modeling/evals/evals.json +24 -0
- package/dist/agent-src/skills/using-git-worktrees/SKILL.md +10 -0
- package/dist/agent-src/skills/verify-completion-evidence/evals/evals.json +16 -0
- package/dist/agent-src/skills/vision-articulation/evals/evals.json +16 -0
- package/dist/agent-src/skills/voice-and-tone-design/evals/evals.json +16 -0
- package/dist/agent-src/skills/worktree-lifecycle/SKILL.md +187 -0
- package/dist/agent-src/skills/worktree-lifecycle/evals/evals.json +38 -0
- package/dist/agent-src/skills/worktree-lifecycle/evals/triggers.json +52 -0
- package/dist/agent-src/templates/agent-settings.md +3 -2
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +15 -1
- package/dist/agent-src/templates/roadmaps.md +14 -0
- package/dist/cli/commands/recordTriggerEval.js +4 -14
- package/dist/cli/commands/recordTriggerEval.js.map +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +374 -88
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +9 -9
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +30 -18
- package/dist/discovery/trust-report.md +5 -5
- package/dist/discovery/workspaces.json +31 -15
- package/dist/install/install.mjs +12 -7
- package/dist/mcp/registry-manifest.json +4 -4
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/claude_settings_hooks.js +8 -0
- package/dist/scripts/_lib/claude_settings_hooks.js.map +1 -1
- package/dist/scripts/_lib/trigger_eval_floors.js +24 -0
- package/dist/scripts/_lib/trigger_eval_floors.js.map +1 -0
- package/dist/scripts/condense.js +12 -2
- package/dist/scripts/condense.js.map +1 -1
- package/dist/server/schemas/settings.js +5 -2
- package/dist/server/schemas/settings.js.map +1 -1
- package/docs/CLAIMS.md +24 -3
- package/docs/architecture.md +3 -3
- package/docs/benchmark.md +51 -0
- package/docs/catalog.md +23 -9
- package/docs/command-flows.md +7 -1
- package/docs/contracts/CHANGELOG-conventions.md +6 -0
- package/docs/contracts/ai-council-config.md +92 -0
- package/docs/contracts/command-clusters.md +1 -0
- package/docs/contracts/design-artifact-lifecycle.md +93 -0
- package/docs/contracts/design-artifact-verification.md +30 -1
- package/docs/contracts/evidence-based-pruning.md +1 -0
- package/docs/contracts/hook-architecture-v1.md +25 -0
- package/docs/contracts/kernel-membership.md +35 -0
- package/docs/contracts/measurement-baseline.md +1 -0
- package/docs/contracts/release-pr-gating.md +26 -0
- package/docs/contracts/release-sizing.md +107 -0
- package/docs/contracts/surface-agent-contracts.md +153 -0
- package/docs/contracts/write-engine.md +38 -1
- package/docs/customization.md +12 -0
- package/docs/decisions/ADR-002-kernel-bucket-overrides.md +11 -0
- package/docs/decisions/ADR-003-flat-cluster-subs-and-colon-syntax.md +11 -0
- package/docs/decisions/ADR-006-skill-tools-python-pilot.md +1 -1
- package/docs/decisions/ADR-028-root-layout.md +1 -1
- package/docs/decisions/ADR-038-canonical-settings-path.md +10 -0
- package/docs/decisions/ADR-092-defer-command-tier-alias-removal.md +29 -5
- package/docs/decisions/ADR-093-ai-council-config-user-global.md +1 -1
- package/docs/decisions/ADR-100-global-knowledge-card-sharing.md +7 -0
- package/docs/decisions/ADR-103-global-knowledge-default-off-until-measured.md +2 -2
- package/docs/decisions/ADR-105-automatic-subagent-orchestration.md +1 -1
- package/docs/decisions/ADR-114-commit-policy-iron-law-override.md +11 -0
- package/docs/decisions/ADR-115-command-cluster-consolidation-phase-4.md +1 -1
- package/docs/decisions/ADR-116-memory-tripwire-activation-path.md +11 -1
- package/docs/decisions/ADR-117-subagents-auto-default-on.md +2 -1
- package/docs/decisions/ADR-118-loop-engineering-boundaries.md +162 -0
- package/docs/decisions/ADR-119-global-knowledge-default-on.md +104 -0
- package/docs/decisions/ADR-200-python-to-typescript-migration.md +11 -1
- package/docs/decisions/ADR-rule-kernel-and-router.md +11 -0
- package/docs/decisions/INDEX.md +11 -9
- package/docs/design/cross-model-parity-eval.md +82 -0
- package/docs/design/length-neutral-judge-rerun.md +92 -0
- package/docs/distribution/consumer-matrix.md +96 -0
- package/docs/featured-skills.md +2 -2
- package/docs/getting-started-by-role.md +1 -1
- package/docs/getting-started.md +2 -2
- package/docs/governance-advantage.md +1 -1
- package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +80 -5
- package/docs/guidelines/code-clarity.md +106 -1
- package/docs/guidelines/design-antipatterns.md +20 -0
- package/docs/guidelines/php/php-coding-patterns.md +12 -2
- package/docs/proof.md +21 -15
- package/docs/release-runbook.md +3 -0
- package/docs/self-review-gate.md +51 -0
- package/docs/wedge/production-validator/production-validator.md +27 -0
- package/package.json +1 -1
- package/src/config/agent-settings.template.yml +29 -9
- package/src/scripts/_cli/cmd_doctor.ts +34 -1
- package/src/scripts/_lib/auto_dispatch.corpus.test.ts +87 -0
- package/src/scripts/_lib/claude_settings_hooks.ts +8 -0
- package/src/scripts/_lib/knowledge_global.ts +6 -2
- package/src/scripts/_lib/knowledge_global_redaction.ts +42 -4
- package/src/scripts/_lib/lexical_index.ts +15 -2
- package/src/scripts/_lib/orchestration_record.ts +27 -0
- package/src/scripts/_lib/orchestration_savings.ts +52 -0
- package/src/scripts/_lib/trigger_eval_floors.ts +31 -0
- package/src/scripts/ai_council/chairman.ts +90 -0
- package/src/scripts/ai_council/clients.ts +18 -3
- package/src/scripts/ai_council/config.ts +157 -0
- package/src/scripts/ai_council/debate_gates.ts +89 -0
- package/src/scripts/ai_council/orchestrator.ts +65 -2
- package/src/scripts/ai_council/prompts.ts +121 -11
- package/src/scripts/ai_council/replay.ts +17 -0
- package/src/scripts/ai_council/stance_tally.ts +184 -0
- package/src/scripts/ai_tells_rules.ts +433 -0
- package/src/scripts/bench_humanizer_eval.ts +240 -0
- package/src/scripts/build_discovery_manifest.ts +6 -0
- package/src/scripts/build_proof.ts +21 -9
- package/src/scripts/check_claims.ts +40 -0
- package/src/scripts/check_release_adjacent_health.ts +121 -0
- package/src/scripts/check_rule_invariants.ts +282 -0
- package/src/scripts/condense.ts +16 -2
- package/src/scripts/consumer_matrix.ts +392 -0
- package/src/scripts/council_cli.ts +147 -0
- package/src/scripts/detect_ai_tells.ts +312 -0
- package/src/scripts/generate_index.ts +3 -2
- package/src/scripts/install.ts +12 -0
- package/src/scripts/knowledge_global_cli.ts +1 -1
- package/src/scripts/lint_changelog_rollback.ts +293 -0
- package/src/scripts/lint_framework_leakage.ts +88 -7
- package/src/scripts/lint_framework_leakage_allowlist.json +59 -572
- package/src/scripts/lint_knowledge_scale.ts +30 -0
- package/src/scripts/lint_originality_shingles.ts +210 -0
- package/src/scripts/orchestration_record.ts +17 -0
- package/src/scripts/orchestration_savings_report.ts +36 -3
- package/src/scripts/schemas/agent-settings.schema.json +11 -0
- package/src/scripts/second_brain_retrieval.ts +44 -2
- package/src/scripts/self_review_gate.test.ts +65 -0
- package/src/scripts/self_review_gate.ts +298 -0
- package/src/scripts/skill_eval_coverage.ts +71 -3
- package/src/scripts/skill_linter.ts +1 -0
- package/src/scripts/trigger_eval_grandfather.json +223 -224
- package/src/scripts/trigger_eval_rotation.ts +344 -0
- package/src/scripts/update_counts.ts +5 -17
- package/src/scripts/worktree_cleanup_check.ts +263 -0
- package/src/server/schemas/settings.ts +8 -3
- package/src/scripts/analysis_freshness.ts +0 -362
- package/src/scripts/export_replay_corpus.ts +0 -208
|
@@ -29,9 +29,7 @@ Three values: `on` (suppress trivial questions), `off` (ask trivial questions to
|
|
|
29
29
|
|
|
30
30
|
## Opt-in detection — match by intent, not exact string
|
|
31
31
|
|
|
32
|
-
In `auto` mode, flip to `on`
|
|
33
|
-
|
|
34
|
-
Algorithm and speech-act heuristic: [`contexts/execution/autonomy-detection.md`](../contexts/execution/autonomy-detection.md). Anchor phrases (DE+EN), no-flip patterns, counter-examples, trivial-vs-blocking taxonomy, commit-policy summary, and named failure modes: [`contexts/execution/autonomy-mechanics.md`](../contexts/execution/autonomy-mechanics.md) + [`contexts/execution/autonomy-examples.md`](../contexts/execution/autonomy-examples.md).
|
|
32
|
+
In `auto` mode, flip to `on` when the user expresses **"stop asking on trivial steps, just work"** — matched by intent, speech-act-checked, reversible; in doubt → no speculative flips. Algorithm: [`contexts/execution/autonomy-detection.md`](../contexts/execution/autonomy-detection.md); summary + anchor phrases + taxonomy: [`contexts/execution/autonomy-mechanics.md`](../contexts/execution/autonomy-mechanics.md) + [`contexts/execution/autonomy-examples.md`](../contexts/execution/autonomy-examples.md).
|
|
35
33
|
|
|
36
34
|
## Task-scope — autonomy is bound to the named task
|
|
37
35
|
|
|
@@ -41,22 +39,7 @@ DOES NOT CARRY OVER TO A DIFFERENT, LATER DELIVERABLE.
|
|
|
41
39
|
NEW TASK → FRESH CONFIRMATION.
|
|
42
40
|
```
|
|
43
41
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
| Shape | Trigger | Scope |
|
|
47
|
-
|---|---|---|
|
|
48
|
-
| **Conversation-wide trivial-question suppression** | "stop asking on trivial steps, just work" — no deliverable named. | Sticky for the rest of the conversation. Suppresses trivial workflow questions only; never lifts blocking, Hard Floor, or [`scope-control`](scope-control.md) gates. |
|
|
49
|
-
| **Task-scoped autonomous execution** | "work autonomously on X", "arbeite die Roadmap Y komplett ab", "do PROJ-123 end-to-end" — a deliverable / artifact / ticket is named. | Bound to **that** task. Ends when the task ends. Does **not** authorize starting a new, distinct task autonomously. |
|
|
50
|
-
|
|
51
|
-
Litmus test: does the directive name (or unambiguously point to) a single concrete deliverable? Yes → task-scoped, scope ends with the deliverable. No → conversation-wide, trivial-question suppression only.
|
|
52
|
-
|
|
53
|
-
When the user later issues a **new** request — different ticket, different roadmap, different artifact, different feature — treat it as a fresh task. Re-confirm autonomy for the new scope before:
|
|
54
|
-
|
|
55
|
-
- creating a branch / worktree / PR / tag for the new work,
|
|
56
|
-
- implementing a roadmap whose **authoring** was the prior turn's deliverable (per [`scope-control § authoring vs implementation`](scope-control.md#authoring-vs-implementation--verb-discipline)),
|
|
57
|
-
- expanding scope beyond the new task's literal ask.
|
|
58
|
-
|
|
59
|
-
In doubt whether the new request inherits or needs fresh confirmation → fresh confirmation. The Hard Floor and [`scope-control`](scope-control.md) gates apply to every task regardless.
|
|
42
|
+
Litmus: does the directive name a single concrete deliverable? Yes → task-scoped, ends with the deliverable; no → conversation-wide trivial-question suppression only. Shapes table, re-confirmation triggers, and the in-doubt default: [`autonomy-mechanics § Task-scope`](../contexts/execution/autonomy-mechanics.md).
|
|
60
43
|
|
|
61
44
|
## User interrupts override the current task
|
|
62
45
|
|
|
@@ -64,7 +47,7 @@ A new instruction from the user mid-flight is **not** a continuation — see [`u
|
|
|
64
47
|
|
|
65
48
|
## Validation-loop budget — hard cap N=3 per target
|
|
66
49
|
|
|
67
|
-
|
|
50
|
+
**Validation target** = a single identifiable artefact (file path, lint rule ID, test name, CI sub-task name) — natural-language clusters ("the linter stuff") don't count.
|
|
68
51
|
|
|
69
52
|
```
|
|
70
53
|
3 CONSECUTIVE FAILED ATTEMPTS ON THE SAME VALIDATION TARGET → STOP.
|
|
@@ -73,7 +56,7 @@ DO NOT ITERATE BEYOND N=3 WITHOUT EXPLICIT USER APPROVAL.
|
|
|
73
56
|
COUNTER RESETS ONLY ON A DIFFERENT TARGET OR USER-APPROVED CONTINUATION.
|
|
74
57
|
```
|
|
75
58
|
|
|
76
|
-
|
|
59
|
+
Failed attempt = an iteration that did not move the target red → green; tuning the tool around the target counts as an attempt.
|
|
77
60
|
|
|
78
61
|
### Antipattern — allowlist-growth as silent budget bypass
|
|
79
62
|
|
|
@@ -82,23 +65,10 @@ ALLOWLIST > 20 ENTRIES IN ONE SESSION = THE LINTER IS WRONG.
|
|
|
82
65
|
STOP. PROPOSE LINTER REDESIGN OR REMOVAL. DO NOT EXPAND THE ALLOWLIST FURTHER.
|
|
83
66
|
```
|
|
84
67
|
|
|
85
|
-
Crossing
|
|
86
|
-
|
|
87
|
-
### Probe efficiency — direct over orchestration
|
|
88
|
-
|
|
89
|
-
When validating a single target, run the **specific** check, not a meta-task that fans out to dozens of sub-tasks. Use the failing tool's direct entry point (the specific script invocation, the specific runner target, the single-test filter for the project's test runner) rather than the full CI meta-pipeline. Full-pipeline runs are appropriate at phase boundaries, not as a per-iteration probe.
|
|
90
|
-
|
|
91
|
-
Concrete tool mapping — verify with the narrowest tool that proves the target green: a single `curl` / Playwright spec / browser run for HTTP behavior, the project's test runner with a `--filter` for one test, a debugger / `xdebug` step-through for one frame. Never substitute a meta-pipeline for a tool that pinpoints the failure.
|
|
92
|
-
|
|
93
|
-
## Adaptive effort & stop (RDP)
|
|
68
|
+
Crossing 20 entries counts as the 3rd validation-target failure — fix the tool shape, not the list. Verify with the narrowest tool that proves the target green (a single `curl` / Playwright spec for HTTP/UI, the test runner with a `--filter`, an `xdebug` step-through) — never a meta-pipeline as per-iteration probe. Failed-attempt detail, suppression-sweep equivalents, probe-efficiency detail, and adaptive effort & stop (RDP): [`autonomy-mechanics § Validation-loop budget`](../contexts/execution/autonomy-mechanics.md).
|
|
94
69
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
(e.g. an `effort` parameter), the right move is to **set it high** for hard tasks
|
|
98
|
-
rather than scaffold; the scaffold here is for a standard host **without** such a
|
|
99
|
-
knob. The per-dimension uncertainty score (see
|
|
100
|
-
[`notes-first-reasoning`](notes-first-reasoning.md)) feeds this decision. Engage
|
|
101
|
-
per [`rdp-gate`](../contexts/execution/rdp-gate.md).
|
|
70
|
+
Body migrated to `contexts/execution/autonomy-mechanics.md` (per P4 of `road-to-kernel-and-router.md`) — opt-in detection summary, task-scope shapes table, N=3 mechanics, allowlist-antipattern detail, probe efficiency, adaptive effort (RDP).
|
|
71
|
+
Trigger-set above activates this routing on demand, independent of the discipline profile (ADR-110).
|
|
102
72
|
|
|
103
73
|
## See also
|
|
104
74
|
|
|
@@ -25,7 +25,7 @@ packs: [engineering-base]
|
|
|
25
25
|
|
|
26
26
|
# Broken Access Control
|
|
27
27
|
|
|
28
|
-
The most common — and most damaging — failure in real systems and AI-written code: log in as one user, see another user's data. **Authenticated ≠ authorized
|
|
28
|
+
The most common — and most damaging — failure in real systems and AI-written code: log in as one user, see another user's data. **Authenticated ≠ authorized** — the per-object ownership/tenant check is the separate line devs and AI omit, especially when the object id comes from the request (OWASP Web #1 A01:2021 / API #1 BOLA/IDOR).
|
|
29
29
|
|
|
30
30
|
## The Iron Law
|
|
31
31
|
|
|
@@ -38,16 +38,6 @@ ROLE DECIDES WHICH FIELDS — THE SERVER STRIPS THEM. THE FRONTEND HIDING A FIEL
|
|
|
38
38
|
A LIVE CROSS-USER EXPOSURE IS A NOTIFIABLE BREACH — NEVER SILENTLY PATCH IT.
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
## Non-optional controls (every data-returning surface)
|
|
42
|
-
|
|
43
|
-
- **Server-derived principal.** Ownership/tenant derived from the session/token, **never** from a request header/param/body the caller controls. A matching id in the request is not authorization.
|
|
44
|
-
- **Ownership/tenant check on every request id** before returning data. `findById(params.id)` with no `where owner/tenant = currentPrincipal` is the canonical bug.
|
|
45
|
-
- **Tenant-scoped by construction.** Every query on a tenant table carries the tenant predicate; prefer a base scope that injects it so a forgotten clause can't leak. (DSGVO: Mandantentrennung / Trennungskontrolle is a required TOM — a missing `tenant_id` filter is a compliance failure, not just a bug.)
|
|
46
|
-
- **Response minimization.** Return only entitled fields — no `SELECT *` / full-object serialization leaking PII "because the model has it" (Art. 25(2)).
|
|
47
|
-
- **Property-level authz (BOPLA / mass assignment).** Reject `role` / `user_id` / `tenant_id` / `is_admin` from the request body; explicit field allow-list, never whole-body binding.
|
|
48
|
-
- **Role/field-level output filtering (vertical BOPLA).** *Which* fields a principal receives depends on role + business rules — a driver role must not receive `price`; an office role must not receive the boss's `offer`. Serialize via a **role-scoped output DTO**, never the raw model / `to_json()`; sensitive fields (`price`/`cost`/`margin`/`salary`/`discount`/`offer`/internal notes) default-deny per role.
|
|
49
|
-
- **No guessable public ids** on sensitive resources — UUID/ULID, not sequential integers (turns one bug into full-DB enumeration).
|
|
50
|
-
|
|
51
41
|
## The three negative tests — the completion gate
|
|
52
42
|
|
|
53
43
|
A protected endpoint is **not complete** until these exist and pass (happy-path 200 alone is the tautology this rule stops):
|
|
@@ -56,38 +46,7 @@ A protected endpoint is **not complete** until these exist and pass (happy-path
|
|
|
56
46
|
2. **authenticated but not the owner → 403/404** (user A requests user B's object with A's token).
|
|
57
47
|
3. **cross-tenant → 403/404** (a principal in tenant A requests tenant B's resource; prefer 404 on sensitive resources — a hard 403 confirms the id exists in another tenant).
|
|
58
48
|
|
|
59
|
-
Small + task-aligned gap in code you touched → add the check **and** its negative test in the same commit (
|
|
60
|
-
|
|
61
|
-
## Role-based field-level access — both directions (vertical BOPLA + BFLA)
|
|
62
|
-
|
|
63
|
-
Object-ownership (above) is *horizontal* (may this principal touch this record). This is *vertical*: which **fields** and which **functions** a role may reach — the maintainer's case (driver ≠ price, office worker ≠ boss's offer). Depends on role + business rules, and **the server is the only boundary** — the frontend hiding a field does not protect it: the raw JSON on the wire is readable via `curl`/DevTools/a proxy (3Fun leak: a privacy toggle filtered only in the app; the server returned every user's location to a direct query).
|
|
64
|
-
|
|
65
|
-
- **Read side (CWE-213 / Excessive Data Exposure).** Build the response from a **role-scoped output DTO** — never serialize the ORM model directly. Sensitive fields default-deny per role. A client `?fields=` selection is ergonomics, not authorization — intersect it server-side with the role's read-allowlist.
|
|
66
|
-
- **Write side (CWE-915).** Bind input through a **role-scoped write-allowlist** — never the raw body. Read-allowed ≠ write-allowed: a role may *see* `status` but not *set* `status:"approved"`; two independent sets.
|
|
67
|
-
- **Function level (BFLA, OWASP API #5).** A role must not reach a function/verb reserved for a higher role. Gate **every mutating verb** (POST/PUT/PATCH/DELETE), deny-by-default — not just the GET you were asked about. The admin button being hidden is not a control.
|
|
68
|
-
- **Nested / GraphQL.** Field-level checks propagate to nested selections; a low-role token selecting a restricted field gets null/error, not data.
|
|
69
|
-
- **Negative tests, per (role × sensitive field), both directions:** lower-role token → the field is **absent from the raw response body** (assert the body, not the UI); lower-role setting it on input → rejected/ignored, **verified by re-reading the persisted record**; every privileged verb → 403 for lower roles (403/404 on sensitive object reads).
|
|
70
|
-
|
|
71
|
-
## Defense-in-depth (so one miss can't leak)
|
|
72
|
-
|
|
73
|
-
Stack ≥2 independent layers on sensitive data — query-level ownership scoping, a centralized default-deny policy layer (a route with no policy is denied, not silently open), and DB row-level security as the backstop for a forgotten `WHERE tenant_id`. The RLS / policy-layer configuration, the per-role authz matrix, and the audit greps live once in [`authz-review`](../skills/authz-review/SKILL.md).
|
|
74
|
-
|
|
75
|
-
## GDPR / DSGVO — data protection by design
|
|
76
|
-
|
|
77
|
-
A cross-user leak violates **Art. 5(1)(f)** (integrity & confidentiality — a principle → higher fine tier), **Art. 25** (by design/default: default-deny + least privilege + response minimization), and **Art. 32** — which also **mandates a process for regularly testing effectiveness** of these controls (untested authz is a direct Art. 32 gap; hence the three negative tests are non-optional). A discovered live exposure is a **notifiable breach** (Art. 33, 72 h from discovery) — surface as "notify + remediate", never a silent patch. Data-protection context, not legal advice → `privacy-review`, `domain-safety-pii`.
|
|
78
|
-
|
|
79
|
-
## Backstop greps (authoring-time)
|
|
80
|
-
|
|
81
|
-
```bash
|
|
82
|
-
# Record fetched by request id with no owner/tenant predicate nearby (high-noise — a hit means read the line, not auto-fix)
|
|
83
|
-
rg -n '(findById|find|findOne|get)\(\s*(req\.|request\.|params\.|\$request|\$id)'
|
|
84
|
-
# Client-supplied tenant/user hint used as the scope (should come from the session)
|
|
85
|
-
rg -n '(tenant|tenantId|user_id|userId)\s*=\s*(req|request|params|headers|query)\.'
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
The full authoring-time grep set (mass-assignment, raw-serialization, secrets) lives once in [`ai-code-blindspots`](../skills/ai-code-blindspots/SKILL.md).
|
|
89
|
-
|
|
90
|
-
A hit means read that line — is the ownership/tenant check present? Some are safe (already scoped); none should ship unchecked.
|
|
49
|
+
Small + task-aligned gap in code you touched → add the check **and** its negative test in the same commit (see `active-remediation` for the auto-fix boundary). Bigger → surface it.
|
|
91
50
|
|
|
92
51
|
## When it fires
|
|
93
52
|
|
|
@@ -95,12 +54,15 @@ Writing/modifying any endpoint, route, query, or serializer returning user- or t
|
|
|
95
54
|
|
|
96
55
|
## When NOT to fire
|
|
97
56
|
|
|
98
|
-
- Public, non-user-specific data with no principal concept (public docs page, health check with no data).
|
|
57
|
+
- Public, non-user-specific data with no principal concept (a public docs page, a health check with no data).
|
|
99
58
|
- Prose/docs/config-only edits.
|
|
100
59
|
|
|
60
|
+
Body migrated to [`skill:authz-review` § Broken-access-control depth](../skills/authz-review/SKILL.md) (per P4 of `road-to-kernel-and-router.md`) — non-optional controls, role-based field-level access (vertical BOPLA + BFLA), defense-in-depth, GDPR/DSGVO grounding, backstop greps.
|
|
61
|
+
Trigger-set above activates this routing on demand, independent of the discipline profile (ADR-110).
|
|
62
|
+
|
|
101
63
|
## See also
|
|
102
64
|
|
|
103
|
-
- [`authz-review`](../skills/authz-review/SKILL.md) — the 6-stage per-entrypoint chain, defense-in-depth, authz matrix, negative-test contract.
|
|
65
|
+
- [`authz-review`](../skills/authz-review/SKILL.md) — the 6-stage per-entrypoint chain, defense-in-depth, authz matrix, negative-test contract, and the migrated depth above.
|
|
104
66
|
- [`security-sensitive-stop`](security-sensitive-stop.md) — threat-model BEFORE editing an auth/tenant path (fires first).
|
|
105
67
|
- [`active-remediation`](active-remediation.md) — the fix-now/ask/follow-up ladder + the live-exposure safety carve-out.
|
|
106
68
|
- [`threat-modeling`](../skills/threat-modeling/SKILL.md), [`multi-tenancy`](../skills/multi-tenancy/SKILL.md), [`ai-code-blindspots`](../skills/ai-code-blindspots/SKILL.md), [`privacy-review`](../skills/privacy-review/SKILL.md).
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: "auto"
|
|
3
|
+
tier: "2b"
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
description: "Writing/editing code in any language — a comment states a WHY or a constraint the code cannot show; never restate what names/types already say; no signature-mirroring docblocks"
|
|
6
|
+
triggers:
|
|
7
|
+
- intent: "writing or generating code"
|
|
8
|
+
- intent: "adding a class / method / function"
|
|
9
|
+
- intent: "refactoring code"
|
|
10
|
+
- keyword: "comment"
|
|
11
|
+
- keyword: "docblock"
|
|
12
|
+
- keyword: "phpdoc"
|
|
13
|
+
- keyword: "jsdoc"
|
|
14
|
+
- keyword: "docstring"
|
|
15
|
+
- keyword: "implement"
|
|
16
|
+
- keyword: "class"
|
|
17
|
+
- keyword: "method"
|
|
18
|
+
- keyword: "refactor"
|
|
19
|
+
workspaces: [engineering]
|
|
20
|
+
packs: [engineering-base]
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# Code Comment Discipline
|
|
24
|
+
|
|
25
|
+
AI-written code over-comments: docblocks mirroring the signature, comments narrating the next line, banner headers, change-log notes. Every redundant comment costs tokens on every future read, bloats the file, rots into misinformation when code changes. Default for any new comment: **no** — a comment must earn its place.
|
|
26
|
+
|
|
27
|
+
## The Iron Law
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
A COMMENT STATES A WHY OR A CONSTRAINT THE CODE CANNOT SHOW — NOTHING ELSE.
|
|
31
|
+
NEVER RESTATE WHAT THE CODE, THE NAME, OR THE TYPE ALREADY SAYS.
|
|
32
|
+
NO DOCBLOCK THAT ONLY MIRRORS THE NATIVE SIGNATURE.
|
|
33
|
+
DOCBLOCKS EARN THEIR PLACE ONLY WITH MACHINE-RELEVANT PRECISION
|
|
34
|
+
(GENERICS, ARRAY SHAPES, NON-TRIVIAL UNIONS) OR GENUINE WHY-CONTEXT.
|
|
35
|
+
WHEN IN DOUBT: NO COMMENT. SHORTER IS BETTER. NONE IS OFTEN BEST.
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## What a comment is FOR
|
|
39
|
+
|
|
40
|
+
Exactly five legitimate jobs — everything else is noise:
|
|
41
|
+
|
|
42
|
+
1. **A why** — non-obvious reason this approach beat the obvious one.
|
|
43
|
+
2. **An invariant or constraint** code can't express — ordering, units, concurrency assumptions, "must run before X".
|
|
44
|
+
3. **A warning** — known trap, workaround for a specific upstream bug (name it), performance cliff.
|
|
45
|
+
4. **Machine-relevant type precision** the native type system can't carry — see carve-out below.
|
|
46
|
+
5. **A spec linkage** where an external contract defines behavior (RFC section, protocol field) — the contract, not ticket history.
|
|
47
|
+
|
|
48
|
+
Test before writing any comment: *would deleting it leave a future reader confused about a non-obvious constraint?* No → don't write it.
|
|
49
|
+
|
|
50
|
+
## Banned comment classes
|
|
51
|
+
|
|
52
|
+
| Banned | Example | Instead |
|
|
53
|
+
|---|---|---|
|
|
54
|
+
| What-narration | `// increment the counter` above `counter++` | Nothing — code says it |
|
|
55
|
+
| Signature-mirroring docblock | `@param string $name The name` on `string $name` | Nothing — typehint says it |
|
|
56
|
+
| Redundant `@return` | `@return bool` on `): bool` | Nothing |
|
|
57
|
+
| Banner / section divider | `// ---------- Helpers ----------` | Structure the file; extract a class |
|
|
58
|
+
| Change-log comment | `// added for the export feature`, `// per ticket #123` | Commit message / PR description |
|
|
59
|
+
| Reviewer-directed justification | `// this is safe because my change …` | PR description |
|
|
60
|
+
| Redundant property docblock | `/** @var LoggerInterface */` on a typed property | Nothing — property type says it |
|
|
61
|
+
| Type-restating JSDoc in typed TS | `/** @param {string} id */` on `id: string` | Nothing — TS carries the type |
|
|
62
|
+
| Obvious docstring | `"""Return the user."""` on `get_user()` | Nothing, or a real contract note |
|
|
63
|
+
| Commented-out code | dead code kept "for reference" | Delete — git history is the tombstone |
|
|
64
|
+
|
|
65
|
+
## Carve-out — machine-relevant precision docblocks STAY
|
|
66
|
+
|
|
67
|
+
Docblock carrying type info the native type system can't express is **not** redundant — static analyzers + IDEs consume it. Keep (and write):
|
|
68
|
+
|
|
69
|
+
- PHP generics / array shapes for PHPStan/Psalm: `@return Collection<int, Post>`, `@param array<string, User> $usersByEmail`, `@template T`, `@phpstan-type`.
|
|
70
|
+
- Union/shape refinements the language can't express natively.
|
|
71
|
+
- Tool-consumed markers: `@deprecated` (with successor), `@internal`, `@throws` for checked flows callers must handle.
|
|
72
|
+
- Python typing only a docstring/stub can carry in the project's toolchain.
|
|
73
|
+
|
|
74
|
+
The line: docblock must add information **beyond** the native signature. `@param array<int, Order> $orders` earns its place; `@param array $orders` does not.
|
|
75
|
+
|
|
76
|
+
## Public-API carve-out — `code_style.docblocks`
|
|
77
|
+
|
|
78
|
+
Read `code_style.docblocks` from `.agent-settings.yml` (missing → `minimal`):
|
|
79
|
+
|
|
80
|
+
- `minimal` (default) — full discipline above; exported/public symbols get no summary docblock unless one of the five legitimate jobs applies.
|
|
81
|
+
- `full` — **exported public surface of a library package** (published API consumers see in their IDE) MAY carry one-line summary docblock per symbol. Redundancy ban holds in `full`: no `@param`/`@return` lines mirroring the signature, ever.
|
|
82
|
+
|
|
83
|
+
## Worked examples
|
|
84
|
+
|
|
85
|
+
```php
|
|
86
|
+
// ❌ Redundant — every line restates the signature
|
|
87
|
+
/**
|
|
88
|
+
* Get the user by id.
|
|
89
|
+
*
|
|
90
|
+
* @param int $id The user id.
|
|
91
|
+
* @return User|null The user or null.
|
|
92
|
+
*/
|
|
93
|
+
public function getUserById(int $id): ?User
|
|
94
|
+
|
|
95
|
+
// ✅ Nothing to add — the signature is the documentation
|
|
96
|
+
public function getUserById(int $id): ?User
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
```php
|
|
100
|
+
// ✅ Docblock KEPT — the generic is machine-relevant (PHPStan), the native type can't carry it
|
|
101
|
+
/** @return Collection<int, Post> */
|
|
102
|
+
public function publishedPosts(): Collection
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
// ❌ Redundant — TS already knows all of this
|
|
107
|
+
/**
|
|
108
|
+
* Formats the price.
|
|
109
|
+
* @param amount - the amount
|
|
110
|
+
* @returns the formatted price
|
|
111
|
+
*/
|
|
112
|
+
export function formatPrice(amount: number): string
|
|
113
|
+
|
|
114
|
+
// ✅ A real constraint the signature can't show
|
|
115
|
+
// Rounds half-up to match the invoice PDF renderer; Intl default is half-even.
|
|
116
|
+
export function formatPrice(amount: number): string
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
# ❌ Narration
|
|
121
|
+
# loop over the items and sum the totals
|
|
122
|
+
total = sum(item.total for item in items)
|
|
123
|
+
|
|
124
|
+
# ✅ A why that survives
|
|
125
|
+
# Stripe amounts are integer cents; convert once at the boundary, never downstream.
|
|
126
|
+
total_cents = sum(item.total_cents for item in items)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Scope boundary
|
|
130
|
+
|
|
131
|
+
Governs **new and edited code only**. Never a license to strip comments from untouched code — [`minimal-safe-diff`](minimal-safe-diff.md) wins on diff shape ("no docstrings/comments on untouched code" cuts both ways: don't add, don't remove). Sweeping a file's existing comments = separate, explicitly-requested cleanup task.
|
|
132
|
+
|
|
133
|
+
## When NOT to fire
|
|
134
|
+
|
|
135
|
+
- Prose surfaces: docs, READMEs, roadmaps, config commentary — different register, not code comments.
|
|
136
|
+
- User explicitly asks for documented code / teaching examples ("erkläre im Code", "annotate this for juniors") — that turn's ask wins.
|
|
137
|
+
- License headers or file-level pragmas a toolchain requires.
|
|
138
|
+
|
|
139
|
+
## Fixtures
|
|
140
|
+
|
|
141
|
+
Behavioral baseline: `tests/code-comments/eval-fixtures.md` (`ccd-php-class-generation`, `ccd-ts-module-generation`, `ccd-untouched-preservation`, `ccd-explicit-teaching-override`); decidable criteria proven by `tests/scripts/code_comment_fixtures.test.ts`.
|
|
142
|
+
|
|
143
|
+
## See also
|
|
144
|
+
|
|
145
|
+
- [`code-clarity.md § Comment discipline`](../docs/guidelines/code-clarity.md#comment-discipline--state-a-constraint-not-a-narration) — canonical long-form with per-language keep/drop tables.
|
|
146
|
+
- [`minimal-safe-diff`](minimal-safe-diff.md) — diff-shape twin; no comment additions or removals on untouched code.
|
|
147
|
+
- [`output-discipline`](output-discipline.md) — adjacent but distinct: bans placeholder prose (`// TODO: implement`); this rule bans redundant prose.
|
|
148
|
+
- `docs/guidelines/php/php-coding-patterns.md` § PHPDoc — PHP-specific operationalization.
|
|
@@ -67,6 +67,20 @@ When **3 consecutive attempts** at the same task fail (code fix, test fix, confi
|
|
|
67
67
|
|
|
68
68
|
**Does NOT reset the counter:** Unrelated tasks. User providing new information (course correction).
|
|
69
69
|
|
|
70
|
+
**Failure identity — same error vs new error.** Failure signature = **same target + same error class** (same failing test + same assertion/exception, same lint rule id, same build error).
|
|
71
|
+
|
|
72
|
+
- **Same failure signature twice → stop and pivot now.** Don't burn the third attempt on a near-identical retry of a fix that already failed the same way — a repeated identical signature means the hypothesis is wrong, not under-applied. Change strategy (re-read source, new hypothesis, ask).
|
|
73
|
+
- **New error signature each attempt = progress.** Peeling one error to reveal a different one is forward motion; counter continues — learning, not looping.
|
|
74
|
+
|
|
75
|
+
**Hard-blocker classes — skip retries, go straight to ask/surface.** On the **first** occurrence, do not count toward the 3 — stop and surface:
|
|
76
|
+
|
|
77
|
+
- Missing credentials / unset required secret or token.
|
|
78
|
+
- Permission denied (auth/authz, file mode, protected branch, scope).
|
|
79
|
+
- Spend / quota / rate limit reached (billing cap, API quota, 429 that won't self-clear).
|
|
80
|
+
- External-service `5xx` / outage / DNS-unreachable — a dependency is down, not your code.
|
|
81
|
+
|
|
82
|
+
Retrying a hard-blocker is the canonical wasted-attempt; the fix is a decision or external change only the user/environment can make.
|
|
83
|
+
|
|
70
84
|
## Tool Loop Detection
|
|
71
85
|
|
|
72
86
|
Calling the **same tool** more than **2 times in a row** with similar parameters = loop.
|
|
@@ -61,22 +61,24 @@ primitive → run in-session (clean no-op).
|
|
|
61
61
|
2. **Tier-size** each slice (`lite|medium|high`) per the classification context —
|
|
62
62
|
never the orchestrator's own session tier (the cost win is the per-call
|
|
63
63
|
downsize; see [`subagent-routing`](../contexts/execution/subagent-routing.md)).
|
|
64
|
-
3. **Dispatch** via the matching `subagent-orchestration` mode
|
|
65
|
-
do-in-parallel; ordered → do-in-steps; risk/correctness →
|
|
64
|
+
3. **Dispatch** via the form gate + matching `subagent-orchestration` mode
|
|
65
|
+
(independent → do-in-parallel; ordered → do-in-steps; risk/correctness →
|
|
66
|
+
+ judge; UI-heavy → live-app judge, efficacy-gated).
|
|
66
67
|
4. **Verify** every return per
|
|
67
68
|
[`verify-budget`](../contexts/execution/verify-budget.md); the cross-model
|
|
68
69
|
judge Iron Law and the N=3 budget ([`autonomous-execution`](autonomous-execution.md))
|
|
69
70
|
are never lifted.
|
|
70
71
|
5. **Respect the failure-type stop and the ordering gate** — two consecutive
|
|
71
72
|
verification-failed returns from one subagent type stop that type for the
|
|
72
|
-
session (an application of the N=3 budget, no new mechanism)
|
|
73
|
-
slice never dispatches before its declared parent's return is
|
|
74
|
-
Both per
|
|
73
|
+
session (an application of the N=3 budget, no new mechanism), and an
|
|
74
|
+
ordered slice never dispatches before its declared parent's return is
|
|
75
|
+
verified. Both per
|
|
76
|
+
[`subagent-steering`](../contexts/execution/subagent-steering.md).
|
|
75
77
|
6. **Record** telemetry after each dispatch — run `orchestration_record`
|
|
76
78
|
(one validated line: spawn_count, token_delta + provenance, tier, task_class)
|
|
77
79
|
per [`orchestration-telemetry`](../contexts/execution/orchestration-telemetry.md)
|
|
78
|
-
§ Emit.
|
|
79
|
-
the value-of-orchestration question unmeasured.
|
|
80
|
+
§ Emit. This is the agent-behavioral capture the savings report reads;
|
|
81
|
+
skipping it leaves the value-of-orchestration question unmeasured.
|
|
80
82
|
|
|
81
83
|
## Scope — does NOT
|
|
82
84
|
|
|
@@ -88,7 +90,7 @@ primitive → run in-session (clean no-op).
|
|
|
88
90
|
|
|
89
91
|
## See also
|
|
90
92
|
|
|
91
|
-
- [`subagent-orchestration`](../skills/subagent-orchestration/SKILL.md) — the
|
|
93
|
+
- [`subagent-orchestration`](../skills/subagent-orchestration/SKILL.md) — the form gate + 8 modes this selects.
|
|
92
94
|
- [`subagent-boundary`](../docs/contracts/subagent-boundary.md) — what a subagent owns vs never owns (task-meaning, memory, pack-surface, safety-floor bypass).
|
|
93
95
|
- [`auto-orchestration-activation`](../contexts/execution/auto-orchestration-activation.md) — the gate.
|
|
94
96
|
- [`reasoning-orchestrator`](../skills/reasoning-orchestrator/SKILL.md) — RDP dispatch, now gated here.
|
|
@@ -88,6 +88,50 @@ redesign.
|
|
|
88
88
|
- Treating an internal "honesty gate" or "stub" concern as licence to redesign the UI.
|
|
89
89
|
- Re-running a redesign after the user already said "match the prototype".
|
|
90
90
|
|
|
91
|
+
## Surgical visual edits
|
|
92
|
+
|
|
93
|
+
A request to change one visual thing — a colour, a label, a single element — is
|
|
94
|
+
a **targeted edit**, not a redesign licence. Apply the same
|
|
95
|
+
[`minimal-safe-diff`](minimal-safe-diff.md) discipline to design work that
|
|
96
|
+
backend edits have always owed.
|
|
97
|
+
|
|
98
|
+
- **Change only the semantic target.** Preserve the surrounding layout,
|
|
99
|
+
spacing, typography, dimensions, content, animation, and interaction states.
|
|
100
|
+
Do not rewrite the component, reflow the section, or "modernise" neighbours
|
|
101
|
+
while you are in there. (fixtures: `daf-edit-preservation`, `daf-unwanted-variations`.)
|
|
102
|
+
- **A broader redesign needs an explicit trigger.** Only phrases like *"new
|
|
103
|
+
direction"*, *"from scratch"*, *"make it feel premium"*, *"rework the flow"*,
|
|
104
|
+
or *"give me variations / options"* license a from-scratch rework. Absent such
|
|
105
|
+
a phrase, a "fix / change / update the X" request is surgical — when unsure
|
|
106
|
+
which, ask ([`ask-when-uncertain`](ask-when-uncertain.md)). (fixture: `daf-redesign-trigger`.)
|
|
107
|
+
- **Preserve stable anchors.** Where the host exposes DOM/comment metadata, keep
|
|
108
|
+
comment anchors and screen labels intact so the edit stays locatable. Where
|
|
109
|
+
the host has no such surface, preserve stable semantic anchors already present
|
|
110
|
+
in source comments / `data-*` attributes — never strip them, and do not invent
|
|
111
|
+
new ones.
|
|
112
|
+
|
|
113
|
+
## Asset & imagery discipline
|
|
114
|
+
|
|
115
|
+
Visual artifacts carry **real assets or honest placeholders — never fabricated
|
|
116
|
+
brand evidence**. The design-surface instance of the no-invented-facts floor.
|
|
117
|
+
|
|
118
|
+
- **Copy owned assets through the project's accepted path.** Reference or copy
|
|
119
|
+
project-owned assets (logos, icons, fonts, images) via the target project's
|
|
120
|
+
asset directory/pipeline — never hotlink a design-system's internal URL, never
|
|
121
|
+
bulk-copy a huge source folder. (fixtures: `daf-missing-asset`, `daf-external-asset-url`.)
|
|
122
|
+
- **Real imagery where inspection matters.** On visual pages/decks, use actual
|
|
123
|
+
product / place / object / state imagery where the image IS the proof (a
|
|
124
|
+
product screenshot, a real dashboard state). Decorative atmosphere is not proof
|
|
125
|
+
— never pass a stock-like or invented image off as the real product. An
|
|
126
|
+
invented product screenshot is fabricated evidence. (fixture: `daf-invented-screenshot`.)
|
|
127
|
+
- **Icons follow the iconography floor** — no emoji-as-icon in serious UI, no
|
|
128
|
+
hand-rolled icon when a set exists; see
|
|
129
|
+
[`iconography`](../skills/iconography/SKILL.md) § Iconography floor.
|
|
130
|
+
- **Ask before adding material — no unrequested filler.** Never generate copy,
|
|
131
|
+
placeholder sections, or decorative blocks the user did not ask for to "complete"
|
|
132
|
+
a design. Brief silent on a region → surface the gap ([`ask-when-uncertain`](ask-when-uncertain.md))
|
|
133
|
+
or leave an honest placeholder; never invent filler to fill space.
|
|
134
|
+
|
|
91
135
|
## See also
|
|
92
136
|
|
|
93
137
|
- [`brand-source-of-truth`](brand-source-of-truth.md) / [`brand-consistency`](brand-consistency.md) — same precedence shape, for registered brand tokens.
|
|
@@ -32,6 +32,8 @@ packs: [engineering-base]
|
|
|
32
32
|
|
|
33
33
|
# Git History Discipline
|
|
34
34
|
|
|
35
|
+
Fires on any rebase / squash / fixup / amend / force-push / `reset --hard` / squash-merge intent, on a divergent local↔origin state, or on a branch carrying commits you did not author this session.
|
|
36
|
+
|
|
35
37
|
## Iron Law — Gate (no unsolicited rewrites)
|
|
36
38
|
|
|
37
39
|
```
|
|
@@ -62,31 +64,6 @@ THAT ALREADY EXISTS ON A BRANCH (LOCAL OR REMOTE) — WITHOUT ASKING
|
|
|
62
64
|
THE USER THIS TURN. PARALLEL WORK IS THE DEFAULT, NOT THE EXCEPTION.
|
|
63
65
|
```
|
|
64
66
|
|
|
65
|
-
The user often works in parallel with the agent, and multiple agents may
|
|
66
|
-
share one PR branch. A commit that looks "unrelated" or "stray" may be
|
|
67
|
-
deliberate in-flight work the user expects to keep. Reseating a branch onto a
|
|
68
|
-
different base, `git reset --hard`-ing away inherited commits, force-pushing
|
|
69
|
-
over a branch you did not create, or branching from a base with unexpected
|
|
70
|
-
commits and then "cleaning" them out all **silently discard work** — the exact
|
|
71
|
-
failure this law prevents.
|
|
72
|
-
|
|
73
|
-
Before ANY of these, STOP and ask (one numbered-options prompt per
|
|
74
|
-
[`user-interaction`](user-interaction.md)):
|
|
75
|
-
|
|
76
|
-
- reseating a branch's base (`git rebase --onto`, `git reset --hard <other-base>`)
|
|
77
|
-
in a way that drops commits already on the branch;
|
|
78
|
-
- excluding / not-carrying-forward commits that were on the branch when you
|
|
79
|
-
started this session;
|
|
80
|
-
- force-pushing (or `push <local>:<remote>`-replacing) a branch that carries
|
|
81
|
-
commits you did not author;
|
|
82
|
-
- branching from a base with unexpected commits, then resetting them away.
|
|
83
|
-
|
|
84
|
-
**Preserve-first is necessary but not sufficient.** Even when you keep the
|
|
85
|
-
commits reachable (a save-branch / tag), you still **ask before** the branch
|
|
86
|
-
the user sees loses them — "I preserved them locally" is not a substitute for
|
|
87
|
-
the question, because the user may be mid-edit on the shared branch and a
|
|
88
|
-
force-push would clobber their in-flight work regardless of your local backup.
|
|
89
|
-
|
|
90
67
|
When in doubt about whether a commit is yours to touch: it is not. Ask.
|
|
91
68
|
|
|
92
69
|
## When rewrite is allowed
|
|
@@ -99,60 +76,8 @@ Exactly three:
|
|
|
99
76
|
|
|
100
77
|
Anything else — chunk-tidiness, "logical order", folding a follow-up fix into its parent — **forbidden**. The follow-up ships as its own commit (`fix: …`, `chore: …`).
|
|
101
78
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
1. **Pre-rewrite stop.** Before any squash / amend / rebase on a branch that is on origin: `git fetch && git rev-list --left-right --count HEAD...@{u}`. If **either** side is non-zero — STOP and route to `skill:git-workflow § Divergent-State Recovery`. A blind `git pull --rebase` in this state is the documented failure mode.
|
|
105
|
-
|
|
106
|
-
2. **Post-rewrite stop.** After the rewrite, push in the **same turn** with `--force-with-lease=<branch>:<fetched-sha>` and verify `git rev-parse origin/<branch>` equals `git rev-parse HEAD`. If the push fails (hook, network, token budget) — fix the cause and re-push **before** ending the session, committing new work, or handing off.
|
|
107
|
-
|
|
108
|
-
If either stop fires and resolution is not immediate → tag the state (`git tag local-rewritten-tip-<ISO-date>`) and hand control back to the user. Do not let a new session inherit a dirty divergence.
|
|
109
|
-
|
|
110
|
-
## Equivalents that are also forbidden by default
|
|
111
|
-
|
|
112
|
-
- `git rebase -i` (interactive)
|
|
113
|
-
- `git rebase --autosquash`
|
|
114
|
-
- `git commit --fixup` / `--squash` (helpers that feed autosquash)
|
|
115
|
-
- `git commit --amend` on already-pushed commits
|
|
116
|
-
- `git push --force` / `--force-with-lease` (unless paired with the protocol)
|
|
117
|
-
- `git reset --hard` past unpushed work the user might want
|
|
118
|
-
- Squash-merge of a PR via API or CLI when the user has not picked the merge strategy
|
|
119
|
-
- Cherry-pick rewriting that drops or reorders commits
|
|
120
|
-
|
|
121
|
-
`--amend` on the *current local* commit before the first push is the narrow exception (treated as continuing to compose the commit, not rewriting history).
|
|
122
|
-
|
|
123
|
-
## Amend-after-hook-failure trap (data-loss)
|
|
124
|
-
|
|
125
|
-
When a **pre-commit hook fails, the commit did NOT happen** — no new commit
|
|
126
|
-
object was created. A reflexive `git commit --amend` at that point does not
|
|
127
|
-
"retry the commit"; it rewrites the **previous, already-good** commit,
|
|
128
|
-
destroying that work. This is the one place the narrow `--amend` exception
|
|
129
|
-
above turns into data loss.
|
|
130
|
-
|
|
131
|
-
Recovery — never amend after a hook failure:
|
|
132
|
-
|
|
133
|
-
1. Read the hook output and **fix the cause** (the lint/test/format failure).
|
|
134
|
-
2. **Re-stage** the fix (`git add`).
|
|
135
|
-
3. Create a **NEW commit** (`git commit`, not `--amend`) — the prior commit was
|
|
136
|
-
never overwritten and must stay intact.
|
|
137
|
-
|
|
138
|
-
Recovery procedures live next to this mechanism in
|
|
139
|
-
[`skill:git-workflow`](../skills/git-workflow/SKILL.md).
|
|
140
|
-
|
|
141
|
-
## Why this rule exists
|
|
142
|
-
|
|
143
|
-
Interactive rebase + fixup loops generate disproportionate token cost on every iteration: re-running CI per replayed commit, resolving the same content conflict in three derived files (`.condensation-hashes.json`, `dist/router.json`, `.windsurfrules`), losing the working tree to a stash that silently re-introduces older state. A single conflict can burn the budget of an entire feature.
|
|
144
|
-
|
|
145
|
-
A previous session squashed a pushed branch, the push hook failed at the token boundary, the session ended — and the next session saw local and origin pointing at different SHAs for the same logical work. A blind `git pull --rebase` cascaded into conflicts across every derived file. Recovery required forensic SHA-archaeology. The pre/post-rewrite stops make that sequence structurally impossible.
|
|
146
|
-
|
|
147
|
-
## When you'd be tempted
|
|
148
|
-
|
|
149
|
-
- "I want commit 3 to come before commit 2 because the topic flows better." → don't. Reviewers read the PR diff.
|
|
150
|
-
- "There are two `chore: regenerate` commits, ugly." → don't. They are honest checkpoints.
|
|
151
|
-
- "A linter caught an issue in commit 2 — let me fold the fix in." → don't. Add `fix(scope): …` on top.
|
|
152
|
-
- "I want to drop the WIP commit before pushing." → ask the user first.
|
|
153
|
-
- "Squash-merge when I open the PR will clean it anyway." → also true, also irrelevant — let the merge strategy do that work, not you.
|
|
154
|
-
- "My branch inherited some unrelated commits — I'll reseat it on `origin/main` so my PR is clean." → **don't, ask first.** They may be the user's parallel work or another agent's. Preserve them and ask which base the user wants.
|
|
155
|
-
- "The remote branch has commits I didn't author and no PR — I'll just force-push over it." → don't. No-PR is not no-owner; ask before replacing a branch you did not create.
|
|
79
|
+
Body migrated to `skill:git-workflow` (per P4 of `road-to-kernel-and-router.md`) — shared-branch ask-before-drop protocol, two protective stops, forbidden-equivalents list, amend-after-hook-failure recovery, why-this-exists rationale, temptation catalog.
|
|
80
|
+
Trigger-set above activates this routing on demand, independent of the discipline profile (ADR-110).
|
|
156
81
|
|
|
157
82
|
## See also
|
|
158
83
|
|