docs(agents): refresh the stale declared≠enforced example in Prime Directive #10#3105
Merged
Conversation
…rective #10 The example cited "the spec declares 9 validation-rule types but the write-path validator enforces only 3" as a live gap. That stopped being true: #1475 was closed by trimming the never-enforced types (unique/async/custom) and fixing enforcement for the rest. Today ValidationRuleSchema declares 6 types (script/state_machine/format/ cross_field/json_schema/conditional) and rule-validator.ts's switch handles all 6 — declared == enforced. Rewritten in the past tense so it reads as a closed loop rather than an open gap. This keeps it serving the principle it illustrates ("never advertise a capability the runtime doesn't deliver") and in fact demonstrates all three of its prescribed verbs: filed (#1475), trimmed (3 types removed), fixed (3 types enforced). A stale example is itself the failure mode the directive warns about — documentation advertising a state the code no longer has. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…rule Adversarial verification of my own rewrite turned up the irony: "the runtime validator enforces all 6" is itself advertising a capability the runtime doesn't fully deliver — exactly what this directive prohibits. evaluateValidationRules() has two call sites (engine.ts:2265 insert, engine.ts:2440 single-id update). The options.multi/updateMany branch never calls it, so on a bulk update all 6 rule types — plus field-level requiredWhen and per-option visibleWhen authorization, which live inside the same evaluator — are silent no-ops. The guard warning there is gated on needsPriorRecord(), which returns false for format/json_schema, so those two fail with no signal at all. #1475's 9-vs-3 gap is genuinely closed; the switch does handle all 6. But "declared == enforced" was true of the switch, not of the system. Reworded to say what's true, and filed #3106 for the call-site hole rather than expanding this docs PR into an engine fix (PD #10). The example now carries the transferable lesson: a case label is not enforcement — check the call site. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Prime Directive #10 in
AGENTS.mdillustrates "never advertise a capability the runtime doesn't deliver" with a validation-rule example that has gone stale:#1475 is closed and that 9-vs-3 split no longer exists. Verified against the tree today:
ValidationRuleSchemadeclaresscript/state_machine/format/cross_field/json_schema/conditionalrule-validator.tsswitch handlesDiffing #1475's list of 6 unenforced types (
unique/format/json_schema/async/custom/conditional) against the 6 that survive shows how it was resolved:unique/async/customwere trimmed (they'd need I/O or a handler model — uniqueness went to a DB index), andformat/json_schema/conditionalgot real enforcement.The example is still true — one layer down
Adversarial verification of my own first draft caught it saying "the runtime validator enforces all 6." That sentence is itself the failure mode this directive prohibits.
evaluateValidationRules()has exactly two call sites:engine.ts:2265(insert) andengine.ts:2440(single-id update). Theoptions.multi→driver.updateManybranch (engine.ts:2442-2487) never calls it. On a bulk update all 6 rule types are silent no-ops — along with field-levelrequiredWhenand per-optionvisibleWhenauthorization, which live inside the same evaluator. The guard warning atengine.ts:2449is gated onneedsPriorRecord(), which returnsfalseforformat/json_schema— so those two fail with no signal at all.Filed as #3106 (
bug+security) rather than fixed here, per this very directive. The wording now says what's true and carries the transferable lesson: acaselabel is not enforcement — check the call site.Why past tense rather than a fresh example
A stale example is itself the thing the directive warns about — docs advertising a state the code no longer has. Swapping in a different live gap just restarts the same clock. The closed-loop account can't drift, and it happens to demonstrate all three verbs the directive prescribes — "fix it, trim it, or file an issue" — in one case: filed (#1475) → trimmed (3 types) → implemented (3 types). The live #3106 pointer then keeps the directive honest about the limit of that fix.
Notes
AGENTS.md. No code or behavior touched — Validation rules, requiredWhen and option visibleWhen are silently skipped on multi-row updates (options.multi) #3106 stays out of this PR deliberately.validation.zod.ts:17-18,rule-validator.ts:35-38— both say "no silent no-ops"). Accurate about the switch, not about the system. Logged in Validation rules, requiredWhen and option visibleWhen are silently skipped on multi-row updates (options.multi) #3106; out of scope here.AGENTS.md:111, merge discipline / auto-merge landing a red PR) is a different claim and still accurate — left alone.skip-changeset: no package changes, nothing user-facing to version.🤖 Generated with Claude Code