feat(context): PR-D C1a — activate agents/commands override + render lift (ADR-0008)#628
Merged
feat(context): PR-D C1a — activate agents/commands override + render lift (ADR-0008)#628
Conversation
…lift (ADR-0008) PR-C #624 shipped the override resolver + matrix gated to skills via ``_PR_C_ACTIVE_TYPES``; PR-D-prep #627 added the agents/commands fan-out application sites as dead code under the same gate. PR-D C1a removes the gate and lifts the ``wiki/override.py`` ``NotImplementedError`` so agents and commands seed via the vendor generator (``parse_canonical_*`` + ``gen.render``), reusing PR-C's layout-aware parsers rather than widening the generator API surface. - ``context/override.py``: drop ``_PR_C_ACTIVE_TYPES`` + the if-branch. ``resolve()`` now returns paths for all rows in ``OVERRIDE_FORMATS``. - ``context/_names.py``: drop the gate-mention comment; tighten the ``("commands", "codex")`` placeholder rationale to point at the runtime ``NotImplementedError`` instead of the gate. - ``wiki/override.py``: ``render_seed_bytes`` lifts the skills-only ``NotImplementedError``. Function-body imports of ``AGENT_GENERATORS`` / ``COMMAND_GENERATORS`` (and the ``parse_canonical_*`` helpers) dodge a wiki ↔ context cycle, since ``context.install`` already imports ``wiki.store``. ``("commands", "codex")`` keeps an explicit ``NotImplementedError`` since ``GENERATOR_VENDOR`` has no ``codex_commands`` entry — preserves the diagnostic UX rather than falling back to a silent ``KeyError``. - ``test_context_override.py``: invert the 4 PR-C/PR-D-prep gate-pin tests. Each rename keeps the original test name in the docstring for series-PR archive value (PR-C #624 + PR-D-prep #627). The 2 fan-out tests use a 3-assertion marker pattern (canonical body absent + override marker present + byte-equality) — extension of ``feedback_pin_invert_symmetric_assertion`` beyond the 2-assertion positive+negative form that PR-D-prep #627 used. - ``test_wiki_override.py`` (new): 3 tests for ``render_seed_bytes`` — agents/codex (TOML format identity), commands/gemini (TOML), and the codex commands ``NotImplementedError`` placeholder pin. C1b (``mm wiki agent override`` / ``mm wiki command override`` CLI mirror) splits to a follow-up PR — adding it would have pushed C1 past the canonical PR-D-glistening-sketch ~280 LOC target. Co-Authored-By: Claude <[email protected]>
…low-up notes PR #628 self-review: ``render_seed_bytes`` is in ``__all__`` and constructs ``store.root / asset_type / name / ...`` paths from the ``name`` parameter. ``seed_override`` (the usual caller) already validates, but a direct call with ``name = "../../etc/passwd"`` would otherwise traverse out of the wiki root. PR-D C1a is the first PR where the agents/commands path-construction code is live (PR-D-prep #627 added it under the ``_PR_C_ACTIVE_TYPES`` gate), so this is the right ship to defend at the function boundary rather than relying on caller discipline. - ``render_seed_bytes`` calls ``validate_name`` on entry. Idempotent with ``seed_override``'s validate (same kind string, same name). - New test ``test_render_seed_bytes_rejects_traversal_name`` covers all 3 asset types with traversal-shaped names. - Inline comment near the ``_dropped`` discard sites flags C1b as the follow-up that will surface dropped vendor fields via stderr WARNING. Co-Authored-By: Claude <[email protected]>
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Summary
PR-D C1a in the ADR-0008 wiki layer series. Removes the PR-C gate
(
_PR_C_ACTIVE_TYPES) and liftswiki/override.py:render_seed_bytesso agents and commands seed via the vendor generator path that PR-D-prep
(#627) already wired into the fan-out. Skills behavior is unchanged.
PR-D split per the canonical plan (
pr-d-glistening-sketch.md):mm wiki agent override/mm wiki command overrideCLI mirror + ~20 mirror tests. Deferred because including it would push C1 past the ~280 LOC target.mm context update/status/install --all/migrate(subsequent PRs).What changed
context/override.py— drop_PR_C_ACTIVE_TYPES+ the gate branch.resolve()now returns paths for every row inOVERRIDE_FORMATS.context/_names.py— drop the gate-mention comment; tighten("commands", "codex")placeholder rationale to point at the runtimeNotImplementedErrorsince the gate is gone.wiki/override.py—render_seed_byteslifts the skills-onlyNotImplementedError. Path (b) parse + render: reuses PR-C's layout-awareparse_canonical_agent/parse_canonical_command+ the existingAGENT_GENERATORS/COMMAND_GENERATORSregistry rather than widening the generator API surface with a newrender_from_canonical(Path)helper. Function-body imports dodge awiki ↔ contextcycle (context.installalready importswiki.store).("commands", "codex")keeps an explicitNotImplementedErrorsinceGENERATOR_VENDORhas nocodex_commandsentry — preserves the diagnostic UX vs a silentKeyError.test_context_override.py— invert the 4 gate-pin tests:test_resolve_skips_agents_in_pr_c→test_resolve_returns_path_for_agents_overridetest_resolve_skips_commands_in_pr_c→test_resolve_returns_path_for_commands_overridetest_agents_fanout_does_not_apply_override_under_gate→test_agents_fanout_applies_claude_override(3-assertion marker pattern)test_commands_fanout_does_not_apply_override_under_gate→test_commands_fanout_applies_claude_override(same)test_wiki_override.py(new, 4 tests) —render_seed_bytesfor agents/codex (TOML), commands/gemini (TOML), the codex commandsNotImplementedErrorplaceholder pin, and the traversal-name rejection guard (added in fixup; see below).3-assertion marker pattern (Step 2 of TDD-ish ordering)
PR-D-prep #627 used a 2-assertion symmetric pin (positive marker present + negative
!=). PR-D extends to 3 assertions:b"Body of the agent." not in body)b"OVERRIDE_MARKER_AGENT" in body)body == override_body)Catches three failure modes: (1) stale canonical leak, (2) wrong override file picked, (3) byte-level corruption. Extension of
feedback_pin_invert_symmetric_assertion.Known limitations (deferred to C1b)
_droppedfields from vendor renderers are silently discarded.Gemini renderer drops
tools/skills/model; codex agents dropstools/skills/isolation/kind/temperature. Users editingthe override file won't realize which fields the vendor runtime can't
represent until C1b surfaces them via stderr WARNING. Inline comment
in
render_seed_bytesflags this as the follow-up.API change
render_seed_bytesraisesNotImplementedErrorwith a new messageformat for
("commands", "codex")(was: skills-onlyNotImplementedErrorpre-PR-D, with message
"override seeding for {asset_type!r} lands in a follow-up PR"). Internal API — no external callers expected.render_seed_bytesparameter rename_vendor→vendor(was unusedfor skills-only path; now load-bearing for vendor dispatch). Internal API.
render_seed_bytesnow callsvalidate_nameon entry (defense-in-depth;see fixup below). Idempotent with
seed_override's validate.Behavior change
<project>/.memtomem/<type>/<name>/overrides/<vendor>.<ext>files (which had no effect under the PR-C gate) now activate. No CLI
created these for agents/commands before C1b, so unlikely in practice;
worth flagging since the gate flip is the activation point.
Fixup commit
fixup(c1a): defense-in-depth validate_name in render_seed_bytes + follow-up notes(0aca0d4). Self-review caught:
render_seed_bytesis in__all__andconstructs
store.root / asset_type / name / ...paths. A traversal-shapednamefrom a direct caller (bypassingseed_override) would escape thewiki root. PR-D C1a is the first PR where the agents/commands branch is
live, so this is the right ship to defend at the function boundary.
validate_name(name, kind=...)at function entry. Idempotent withseed_override's existing validate.test_render_seed_bytes_rejects_traversal_namecovers all 3 assettypes with traversal-shaped names.
_droppedfollow-up.Test plan
uv run pytest packages/memtomem/tests/test_context_override.py -v— 13 pass (4 inverted + 9 unchanged).uv run pytest packages/memtomem/tests/test_wiki_override.py -v— 4 pass (new file; 3 + traversal guard).uv run pytest packages/memtomem/tests/test_wiki_cmd_override.py -v— 10 pass (skills CLI surface unchanged).uv run pytest packages/memtomem/tests/ -m "not ollama" -q— 3453 pass, 46 deselected. No regressions.uv run ruff check packages/memtomem/src packages/memtomem/tests— clean.uv run ruff format --check packages/memtomem/src packages/memtomem/tests— clean.test_render_seed_bytes_*exercise function-body imports at call time; ImportError would surface there.Out of scope
installed_atcapture move (PR-B contract micro-fixup) — first sub-commit of the C2 PR.🤖 Generated with Claude Code