Skip to content

Commit 8ffddba

Browse files
dmealingclaude
andcommitted
docs(agent-context): ship the "loaded metadata is read-only" anti-pattern to adopter projects
Add a Principles bullet to the always-on agent context (scaffolded into every adopter project by `meta init` / `*:agent-docs` across all five ports): never inject nodes or mutate the loaded metadata tree at load time — author the field in the metadata, or derive it during codegen (read metadata → emit output). This is the adopter-facing form of the durable rule from the AI-trace design reversal. Regenerated the agent-context-conformance goldens (AGENTS.md + CLAUDE.md × 4 stacks) via the shared assembler. Verified: TS agent-context conformance + size-gate 5/5; Python agent-context conformance 5/5 (cross-port byte-identity holds with the new line). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 667302f commit 8ffddba

9 files changed

Lines changed: 9 additions & 0 deletions

File tree

agent-context/templates/always-on.md.mustache

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ spine; generated code is the disposable artifact. Regenerate with `{{codegenComm
99
- Pattern-derivable from metadata = codegen, never hand-write (FKs, CRUD, validators, finders).
1010
- Never hand-edit generated files — change the metadata and regenerate (three-way merge preserves hand-written regions).
1111
- Use the generated constants for any string that names metadata.
12+
- The loaded metadata model is READ-ONLY — never inject nodes or mutate the tree at load time (no "enrich the model on load" hooks). Need an extra field/column? Author it in the metadata, or derive it during codegen (read the metadata, emit output). Mutating the loaded model makes it diverge from what's declared — a bad practice reserved for very rare cases.
1213

1314
## Authoring rules you must not violate
1415
- Nodes are fused-key maps: `{"<type>.<subType>": { ... }}` (e.g. `{"field.string": {"name": "email"}}`) — never split the type and subtype into separate keys.

fixtures/agent-context-conformance/java-kotlin-react-tanstack/expected/.metaobjects/AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ spine; generated code is the disposable artifact. Regenerate with `mvn metaobjec
99
- Pattern-derivable from metadata = codegen, never hand-write (FKs, CRUD, validators, finders).
1010
- Never hand-edit generated files — change the metadata and regenerate (three-way merge preserves hand-written regions).
1111
- Use the generated constants for any string that names metadata.
12+
- The loaded metadata model is READ-ONLY — never inject nodes or mutate the tree at load time (no "enrich the model on load" hooks). Need an extra field/column? Author it in the metadata, or derive it during codegen (read the metadata, emit output). Mutating the loaded model makes it diverge from what's declared — a bad practice reserved for very rare cases.
1213

1314
## Authoring rules you must not violate
1415
- Nodes are fused-key maps: `{"<type>.<subType>": { ... }}` (e.g. `{"field.string": {"name": "email"}}`) — never split the type and subtype into separate keys.

fixtures/agent-context-conformance/java-kotlin-react-tanstack/expected/.metaobjects/CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ spine; generated code is the disposable artifact. Regenerate with `mvn metaobjec
99
- Pattern-derivable from metadata = codegen, never hand-write (FKs, CRUD, validators, finders).
1010
- Never hand-edit generated files — change the metadata and regenerate (three-way merge preserves hand-written regions).
1111
- Use the generated constants for any string that names metadata.
12+
- The loaded metadata model is READ-ONLY — never inject nodes or mutate the tree at load time (no "enrich the model on load" hooks). Need an extra field/column? Author it in the metadata, or derive it during codegen (read the metadata, emit output). Mutating the loaded model makes it diverge from what's declared — a bad practice reserved for very rare cases.
1213

1314
## Authoring rules you must not violate
1415
- Nodes are fused-key maps: `{"<type>.<subType>": { ... }}` (e.g. `{"field.string": {"name": "email"}}`) — never split the type and subtype into separate keys.

fixtures/agent-context-conformance/java-react/expected/.metaobjects/AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ spine; generated code is the disposable artifact. Regenerate with `mvn metaobjec
99
- Pattern-derivable from metadata = codegen, never hand-write (FKs, CRUD, validators, finders).
1010
- Never hand-edit generated files — change the metadata and regenerate (three-way merge preserves hand-written regions).
1111
- Use the generated constants for any string that names metadata.
12+
- The loaded metadata model is READ-ONLY — never inject nodes or mutate the tree at load time (no "enrich the model on load" hooks). Need an extra field/column? Author it in the metadata, or derive it during codegen (read the metadata, emit output). Mutating the loaded model makes it diverge from what's declared — a bad practice reserved for very rare cases.
1213

1314
## Authoring rules you must not violate
1415
- Nodes are fused-key maps: `{"<type>.<subType>": { ... }}` (e.g. `{"field.string": {"name": "email"}}`) — never split the type and subtype into separate keys.

fixtures/agent-context-conformance/java-react/expected/.metaobjects/CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ spine; generated code is the disposable artifact. Regenerate with `mvn metaobjec
99
- Pattern-derivable from metadata = codegen, never hand-write (FKs, CRUD, validators, finders).
1010
- Never hand-edit generated files — change the metadata and regenerate (three-way merge preserves hand-written regions).
1111
- Use the generated constants for any string that names metadata.
12+
- The loaded metadata model is READ-ONLY — never inject nodes or mutate the tree at load time (no "enrich the model on load" hooks). Need an extra field/column? Author it in the metadata, or derive it during codegen (read the metadata, emit output). Mutating the loaded model makes it diverge from what's declared — a bad practice reserved for very rare cases.
1213

1314
## Authoring rules you must not violate
1415
- Nodes are fused-key maps: `{"<type>.<subType>": { ... }}` (e.g. `{"field.string": {"name": "email"}}`) — never split the type and subtype into separate keys.

fixtures/agent-context-conformance/python/expected/.metaobjects/AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ spine; generated code is the disposable artifact. Regenerate with `metaobjects g
99
- Pattern-derivable from metadata = codegen, never hand-write (FKs, CRUD, validators, finders).
1010
- Never hand-edit generated files — change the metadata and regenerate (three-way merge preserves hand-written regions).
1111
- Use the generated constants for any string that names metadata.
12+
- The loaded metadata model is READ-ONLY — never inject nodes or mutate the tree at load time (no "enrich the model on load" hooks). Need an extra field/column? Author it in the metadata, or derive it during codegen (read the metadata, emit output). Mutating the loaded model makes it diverge from what's declared — a bad practice reserved for very rare cases.
1213

1314
## Authoring rules you must not violate
1415
- Nodes are fused-key maps: `{"<type>.<subType>": { ... }}` (e.g. `{"field.string": {"name": "email"}}`) — never split the type and subtype into separate keys.

fixtures/agent-context-conformance/python/expected/.metaobjects/CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ spine; generated code is the disposable artifact. Regenerate with `metaobjects g
99
- Pattern-derivable from metadata = codegen, never hand-write (FKs, CRUD, validators, finders).
1010
- Never hand-edit generated files — change the metadata and regenerate (three-way merge preserves hand-written regions).
1111
- Use the generated constants for any string that names metadata.
12+
- The loaded metadata model is READ-ONLY — never inject nodes or mutate the tree at load time (no "enrich the model on load" hooks). Need an extra field/column? Author it in the metadata, or derive it during codegen (read the metadata, emit output). Mutating the loaded model makes it diverge from what's declared — a bad practice reserved for very rare cases.
1213

1314
## Authoring rules you must not violate
1415
- Nodes are fused-key maps: `{"<type>.<subType>": { ... }}` (e.g. `{"field.string": {"name": "email"}}`) — never split the type and subtype into separate keys.

fixtures/agent-context-conformance/ts-react-tanstack/expected/.metaobjects/AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ spine; generated code is the disposable artifact. Regenerate with `npx meta gen`
99
- Pattern-derivable from metadata = codegen, never hand-write (FKs, CRUD, validators, finders).
1010
- Never hand-edit generated files — change the metadata and regenerate (three-way merge preserves hand-written regions).
1111
- Use the generated constants for any string that names metadata.
12+
- The loaded metadata model is READ-ONLY — never inject nodes or mutate the tree at load time (no "enrich the model on load" hooks). Need an extra field/column? Author it in the metadata, or derive it during codegen (read the metadata, emit output). Mutating the loaded model makes it diverge from what's declared — a bad practice reserved for very rare cases.
1213

1314
## Authoring rules you must not violate
1415
- Nodes are fused-key maps: `{"<type>.<subType>": { ... }}` (e.g. `{"field.string": {"name": "email"}}`) — never split the type and subtype into separate keys.

fixtures/agent-context-conformance/ts-react-tanstack/expected/.metaobjects/CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ spine; generated code is the disposable artifact. Regenerate with `npx meta gen`
99
- Pattern-derivable from metadata = codegen, never hand-write (FKs, CRUD, validators, finders).
1010
- Never hand-edit generated files — change the metadata and regenerate (three-way merge preserves hand-written regions).
1111
- Use the generated constants for any string that names metadata.
12+
- The loaded metadata model is READ-ONLY — never inject nodes or mutate the tree at load time (no "enrich the model on load" hooks). Need an extra field/column? Author it in the metadata, or derive it during codegen (read the metadata, emit output). Mutating the loaded model makes it diverge from what's declared — a bad practice reserved for very rare cases.
1213

1314
## Authoring rules you must not violate
1415
- Nodes are fused-key maps: `{"<type>.<subType>": { ... }}` (e.g. `{"field.string": {"name": "email"}}`) — never split the type and subtype into separate keys.

0 commit comments

Comments
 (0)