docs(adr): ADR 0076 Amendment E -- writable templated mode, GRAMMAR ONLY, no code built (BACKLOG #237) - #548
Merged
Conversation
… no code built (BACKLOG #237) Executes the owner's 2026-08-23 ruling that `templated` is writable in v1 and that this ADR is to be amended for it. The amendment is the gated step that must land before any code; NOTHING IS IMPLEMENTED and all seven acceptance criteria are unchecked. WHY AN AMENDMENT IS REQUIRED AT ALL, stated narrowly because the read-only reading would have needed none. Section 4 admits an action row's arguments as "literal args or bounded Message-read expressions". Static writes a literal, already admitted; a path picker writing one bounded msg read is also already admitted. Templated means an INTERPOLATION, which is neither -- so a writable templated makes `lens rewrite` emit a shape the grammar does not accept. Section 2 binds "grammar" to section 4 explicitly. The sibling item proves the cheaper reading existed: #235 closed saying it "widens what is editable without widening the recognition grammar". Same seam, same surface, no amendment. This one differs only because the owner chose writable over read-only, having been offered and declined a defer-past-v1 third option. E.3 IS THE LOAD-BEARING SECTION AND IT IS WHY THE TWO MODES DIVERGE. Templated is a bounded, enumerable shape, so a rewriter can emit it AND read it back to the same mode -- round-trip is total over the admitted set, and that totality is what licenses writing. Dynamic is "everything else" by construction, an open set, and a rewriter cannot round-trip an open set. So the rule generalises rather than special-cases: a mode is writable exactly when its shape is bounded enough to round-trip. It reuses the same boundedness test section 4 already applies to control-row tests. E.5 states the admitted interpolation as a CLOSED SET with an explicit exclusion list, not as a predicate over safe-looking expressions. An open predicate is a second grammar that drifts from the first -- the failure scripts/quality/lens_coverage.py already refuses by driving the shipped `lens parse --json` rather than reimplementing recognition. TWO THINGS RECORDED SO A LATER READER DOES NOT "FIX" THEM: E.2 the sketch's own words -- "dynamic mode stays read-only in v1 so no new rewrite class is introduced" -- are OVERRIDDEN FOR TEMPLATED ONLY and still govern dynamic. Two sibling modes with opposite writability under one sentence that appears to forbid both reads as an inconsistency without this paragraph. E.7 the #26 line. The .py stays the only artifact and the only execution path, which is that carve-out's stated test. Declarative logic execution, declarative field-mapping and drag-drop canvas authoring remain declined. E.6 re-asserts the section 5 invariants as build gates rather than caveats, because a new emit path is the thing most likely to break byte-stable splicing and the exact-partition coverage invariant. E.6.4 is the one a passthrough implementation would quietly violate: a dynamic argument must be REFUSED, never re-emitted from its own source. VERIFIED: zero characters above U+2500 in the added text, with a planted U+2705 as the positive control; the four in the file are pre-existing. Line endings consistently LF. Co-Authored-By: Claude Opus 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.
Docs only. One file,
docs/adr/0076-typed-action-vocabulary-action-list-lens.md, 177 insertions, no existing line touched.What this is, and what it is not
Grammar only. Nothing is implemented. All seven acceptance criteria are deliberately unchecked, and the commit subject says so, so a reader lands on that fact rather than discovering it.
This is the gated step that must land before any #237 code, which is why it wants ordinary review rather than speed.
It executes an owner ruling and guards its own boundary
Section E.2 records the ruling it implements — "templated is writable in v1, and this ADR is to be amended for it" — including that a third option, writable but deferred past v1, was offered and declined.
Section E.7 Non-goals is the part worth reading: each entry names how this becomes a different, declined feature. It restates the
#26carve-out test explicitly — the.pystays the only artifact and the only execution path — and confirms that declarative field-mapping and drag-drop canvas authoring remain declined.That matters because "templated mode" is exactly the phrase that would otherwise read as crossing
#26, which is declined-by-design. The amendment does not quietly widen that line; it names it and stays inside it.Verification
origin/maindirectly, not from sec(gitleaks): a low-entropy defaulted credential passes both required secret gates (BACKLOG #1091) #545 or sec(hooks): the claim gate's deny text interpolates peer-written values into prose a model then acts on (BACKLOG #1040) #547, so backlog: file #1063, setup-leak-gate.ps1 arms the checkout it is standing in #237 does not ride on either.U+2705as the positive control. The four already in the file are pre-existing.That non-zero check is not decoration — I shipped a screen against an empty diff earlier today whose controls passed while it examined nothing, so the added-line count is now part of the screen rather than an assumption.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com
🤖 Generated with Claude Code