feat(resync): notify a live agent when a declared resource carrier changes - #345
Conversation
|
@codex please review Posted on behalf of @schickling
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a6463c72e5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex please review the current head Posted on behalf of @schickling
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 52132aecd2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d19223d7f6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5823ea41c7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b30015eacb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8e8e3f059c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 61d292be0d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6b8be04fad
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 04185095ec
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 11c6d218a1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c70d56028b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: db5cd6b150
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5e566990e3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 55e0e96d36
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ad4b6f54db
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: db2477e684
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cb5c03e045
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6778ba26c8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
74bcb20 to
0a88ab2
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0a88ab2f39
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
A resource binding uri may now be a scheme-less relative path, resolved by the consumer against the declaration directory. Absolute URIs keep the existing validation. This is the carrier form declaratively managed goal files need (docs/vrs/06-resync); it is an st2 extension pending canonical Agent Spec adoption. agent-identity: unknown agent-persona: generalist agent-supervisor: unavailable agent-tool: OMP agent-tool-version: 18.0.3 agent-runtime: OMP 18.0.3 tooling-profile: dotfiles@a80129b-dirty
…anges Implements #341. The supervisor watches each running agent's local resource carriers (file:// and catalog-relative bindings plus its own declaration), classifies them (immediate / silent / coalesced), and emits digest-keyed, superseded events through a built-in reserved `resync` stream on the unchanged event-stream ingress. Equal-byte rewrites never wake; bursts coalesce per class window. Design decisions: docs/vrs/.decisions/0008; subsystem VRS: docs/vrs/06-resync. agent-identity: unknown agent-persona: generalist agent-supervisor: unavailable agent-tool: OMP agent-tool-version: 18.0.3 agent-runtime: OMP 18.0.3 tooling-profile: dotfiles@a80129b-dirty
A reconcile pass can land between a carrier mutation and its flush window (agent.kdl changes wake reconcile immediately). Reseeding digests on every watch-set application silently erased that pending event; carriers already on record now keep their digest and dirty state, and only genuinely unknown paths seed silently. agent-identity: unknown agent-persona: generalist agent-supervisor: unavailable agent-tool: OMP agent-tool-version: 18.0.3 agent-runtime: OMP 18.0.3 tooling-profile: dotfiles@a80129b-dirty
…periment agent-identity: unknown agent-persona: generalist agent-supervisor: unavailable agent-tool: OMP agent-tool-version: 18.0.3 agent-runtime: OMP 18.0.3 tooling-profile: dotfiles@a80129b-dirty
- run: restore unpark report merging and the crash-loop dedup reset in the supervisor loop, lost when the resync wiring landed - resync: derive the event identity from the whole transition (previous digest -> new digest), so an A->B->A oscillation re-notifies on the rollback leg instead of colliding with B's original identity - resync: resolve bus ids with the supervisor's logical host, so hostless declarations supervised under `st2 up --host <alias>` produce recipients the ingress can actually resolve - resync: retain every subscriber of a shared carrier path; several agents binding one file each get their own event - resync: carriers whose parent directory cannot be registered fall back to digest polling at refresh cadence instead of being watched by nobody agent-identity: unknown agent-persona: generalist agent-supervisor: unavailable agent-tool: OMP agent-tool-version: 18.0.3 agent-runtime: OMP 18.0.3 tooling-profile: dotfiles@a80129b-dirty
…up test The shell's > redirection creates an empty pidfile before printf writes, so polling is_file() can observe an empty file under CI load and panic with ParseIntError::Empty. Poll for parseable content instead. agent-identity: unknown agent-persona: generalist agent-supervisor: unavailable agent-tool: OMP agent-tool-version: 18.0.3 agent-runtime: OMP 18.0.3 tooling-profile: dotfiles@a80129b-dirty
220b4ad to
410b95e
Compare
410b95e to
0708d42
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0708d42717
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
#351 landed first and rewrote R20: a binding's URI scheme is now the exact lookup key for an optional, catalog-declared Resource Profile, scheme meaning stays downstream-owned, and st2 ships no built-in profiles. Drop R35. It existed only because R20 then read "st2 does not register schemes", which a scheme st2 resolves would have contradicted; it granted an exemption from a clause R20 no longer contains, so rebasing it would have carried a self-contradiction into requirements.md. `working-state` needs no exemption under the merged R20 — st2 writes the carrier through `st2 context`, and resolving the scheme is a catalog's choice. requirements.md is now identical to main: this branch makes no constitutional edit. Decision 0012 records the withdrawal as an amendment rather than rewriting its history. Nothing about the carrier, its scheme name, or its realization changes. Renumber this branch's decisions 0008/0009/0010 to 0011/0012/0013; #351 and #345 took 0008 and 0009 on main. Correct three places that asserted the pre-#351 contract: the ontology's Resource and working-state entries, and 07-resource/spec.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> agent-identity: unknown agent-persona: generalist agent-supervisor: unavailable agent-tool: Claude Code agent-tool-version: 2.1.237 agent-runtime: Claude Code 2.1.237 tooling-profile: dotfiles@11eaf2d-dirty
#345 admits a catalog-relative carrier path as a binding uri, not only an absolute URI, and reserves the binding name `declaration` for resync. Three assertions written against the older contract went stale on the rebase: - `agent_author` refused `./issue/1` and `example.com/issue/1`; both are valid relative carriers now. The refusals worth pinning are the ones that escape the catalog (`/etc/passwd`, `../outside`), so those replace them, and a positive case pins that `carriers/goal.md` is admitted. - `agent_resource` asserted a non-absolute uri is refused; it now asserts the escaping paths are refused and that the resync-reserved name is refused. - `agent_publish` drove the retired link-plane `resource add <url>` as a state-plane write under an incomplete-apply marker. A binding write is a declaration write, so it probes `context append` for the state plane and now additionally asserts the marker fences `resource add` — the behaviour that moving planes makes correct. Verified against a same-toolchain `git archive origin/main` baseline: the branch's failing-target set is a strict subset of main's own. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> agent-identity: unknown agent-persona: generalist agent-supervisor: unavailable agent-tool: Claude Code agent-tool-version: 2.1.237 agent-runtime: Claude Code 2.1.237 tooling-profile: dotfiles@11eaf2d-dirty
…rface (#361) * docs(vrs): retire the linked-record plane; add R35 st2-owned Resource profiles st2 carried two disjoint durable edges both called "resource": Agent Spec Resource bindings, and the link records written by `st2 resource add`. Nothing in the corpus said they were disjoint, and `ontology.md` — the disambiguation index that exists to prevent exactly this — defined neither. Measured on one live catalog of 655 declarations: 889 distinct binding URIs and 233 distinct link-record URLs share zero members, exactly and after normalization on all five schemes both planes used. The planes are disjoint by construction — bindings carry what an agent is for, link records carried what it made — so a shared descriptor type deduplicates nothing. The link plane was write-only (its only reader was its own `ls`/`read` verb), adopted by 12.5% of declarations, decaying, and superseded by `axe work update --artifact/--pty`. It is retired. The drift between the planes was caused by write-cost asymmetry, not by two concepts sharing a word: 45 of 241 link records were dependency edges filed in a products store, because a binding needed publisher authority plus whole-declaration CAS republication while a link record was one file write. Adds the 07-resource tree, ontology entries for Resource, Resource binding, linked record (retired), agent resource directory, and working state, and three decision records. R35 names the st2-owned Resource profiles that R20's "st2 does not register schemes" otherwise forbids, so `working-state` can exist without leaving R20 contradicted. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> agent-identity: unknown agent-persona: generalist agent-supervisor: unavailable agent-tool: Claude Code agent-tool-version: 2.1.237 agent-runtime: Claude Code 2.1.237 tooling-profile: dotfiles@11eaf2d-dirty * feat(resource): repoint `st2 resource` at declared bindings with mediated writes `st2 resource` managed link records under `<agent-dir>/resources/links/` — a plane nothing read, that 12.5% of declarations used, and that `axe work update --artifact/--pty` has superseded. It is removed, and the verb now reads and writes the plane that has the spec authority. st2 resource ls [<identity>] [--json] st2 resource read [<identity>] <name> [--json] st2 resource add <name> --uri <uri> --reason <text> [--inactive-reason <text>] st2 resource remove <name> st2 resource rename <old> <new> `ls`/`read` project declared bindings; bindings previously had no human surface at all, which is why agents reaching for `st2 resource ls` measured the other store. The write verbs do read-modify-CAS-publish internally so the caller never renders KDL, and they are the fourth caller of the `agent_author` pattern after streams, desired state, and presentation — full-catalog validation, exact-target selection, compare-and-swap, fail-closed concurrent change, and the Nix-managed refusal all come from the existing machinery. A binding-only change does not relaunch healthy work (R21), and URI bytes are preserved without normalization (R20). `<agent-dir>/resources/` is untouched and remains canonical for an agent's resource files; only `links/` goes. Two `catalog_apply` tests used `st2 resource add` as a state-plane write probe. That is now a declaration-plane write, so they probe `context append` and `message send` instead — the writers that still route through `with_resolved_state_dir`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> agent-identity: unknown agent-persona: generalist agent-supervisor: unavailable agent-tool: Claude Code agent-tool-version: 2.1.237 agent-runtime: Claude Code 2.1.237 tooling-profile: dotfiles@11eaf2d-dirty * fix(resource): drop the dead `links` state-dir entry; correct the ls example ordering `marker_state_exists` still validated `resources/links` as a real directory. st2 no longer owns that path — the linked-record plane is retired and nothing reads or writes there — so asserting on it is stale vocabulary. The orphaned directories remain on disk untouched; st2 simply stops making claims about them. The 07-resource worked example listed bindings in declaration order. `ls` sorts by name, which is correct: declaration order has no meaning. Verified against the real catalog byte-for-byte, including the width-aware name padding. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> agent-identity: unknown agent-persona: generalist agent-supervisor: unavailable agent-tool: Claude Code agent-tool-version: 2.1.237 agent-runtime: Claude Code 2.1.237 tooling-profile: dotfiles@11eaf2d-dirty * fix(resource): handle a binding's trailing line comment on remove and update A hand-authored `resource "work" uri="…" reason="…" // why it is here` could not be removed: `remove_field`'s standalone-line path accepted only whitespace after the node, so it fell through to the compact path and refused with `unsafe-source-shape`. The line's own trailing `//` comment is now removable trivia and goes with the binding it explains. `/*` is deliberately not accepted — a block comment can span lines and this only ever sees one. Updating the same binding had a quieter defect: the node span runs to the start of trailing trivia, so replacing it verbatim glued the rendered node onto the comment (`reason="Changed."// why`). The separator is now preserved. The output still parsed, so this was cosmetic rather than corrupting. Reported by Codex review on #361 (P2). The remove case is the one that hard-failed; the update case was found while confirming the scope. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> agent-identity: unknown agent-persona: generalist agent-supervisor: unavailable agent-tool: Claude Code agent-tool-version: 2.1.237 agent-runtime: Claude Code 2.1.237 tooling-profile: dotfiles@11eaf2d-dirty * docs(vrs): reconcile with the merged Resource Profile foundation #351 landed first and rewrote R20: a binding's URI scheme is now the exact lookup key for an optional, catalog-declared Resource Profile, scheme meaning stays downstream-owned, and st2 ships no built-in profiles. Drop R35. It existed only because R20 then read "st2 does not register schemes", which a scheme st2 resolves would have contradicted; it granted an exemption from a clause R20 no longer contains, so rebasing it would have carried a self-contradiction into requirements.md. `working-state` needs no exemption under the merged R20 — st2 writes the carrier through `st2 context`, and resolving the scheme is a catalog's choice. requirements.md is now identical to main: this branch makes no constitutional edit. Decision 0012 records the withdrawal as an amendment rather than rewriting its history. Nothing about the carrier, its scheme name, or its realization changes. Renumber this branch's decisions 0008/0009/0010 to 0011/0012/0013; #351 and #345 took 0008 and 0009 on main. Correct three places that asserted the pre-#351 contract: the ontology's Resource and working-state entries, and 07-resource/spec.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> agent-identity: unknown agent-persona: generalist agent-supervisor: unavailable agent-tool: Claude Code agent-tool-version: 2.1.237 agent-runtime: Claude Code 2.1.237 tooling-profile: dotfiles@11eaf2d-dirty * docs(vrs): scope the resource boundaries to this document, not to st2 "No Resource registry, no generic resolution" described st2 before #351 landed one. Resolution is out of scope for 07-resource, not absent from st2: the scheme-keyed profile registry lives in 07-resource-profile. The two are orthogonal — a binding names a Resource whether or not a profile resolves its scheme, and `st2 resource` neither reads nor requires one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> agent-identity: unknown agent-persona: generalist agent-supervisor: unavailable agent-tool: Claude Code agent-tool-version: 2.1.237 agent-runtime: Claude Code 2.1.237 tooling-profile: dotfiles@11eaf2d-dirty * test: align resource validation coverage with the widened #345 envelope #345 admits a catalog-relative carrier path as a binding uri, not only an absolute URI, and reserves the binding name `declaration` for resync. Three assertions written against the older contract went stale on the rebase: - `agent_author` refused `./issue/1` and `example.com/issue/1`; both are valid relative carriers now. The refusals worth pinning are the ones that escape the catalog (`/etc/passwd`, `../outside`), so those replace them, and a positive case pins that `carriers/goal.md` is admitted. - `agent_resource` asserted a non-absolute uri is refused; it now asserts the escaping paths are refused and that the resync-reserved name is refused. - `agent_publish` drove the retired link-plane `resource add <url>` as a state-plane write under an incomplete-apply marker. A binding write is a declaration write, so it probes `context append` for the state plane and now additionally asserts the marker fences `resource add` — the behaviour that moving planes makes correct. Verified against a same-toolchain `git archive origin/main` baseline: the branch's failing-target set is a strict subset of main's own. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> agent-identity: unknown agent-persona: generalist agent-supervisor: unavailable agent-tool: Claude Code agent-tool-version: 2.1.237 agent-runtime: Claude Code 2.1.237 tooling-profile: dotfiles@11eaf2d-dirty --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Closes #341. Refs #286 (delivery machinery), #305 (Nix-managed spec composition).
Problem
An agent's context is assembled from its declared resources. When a carrier file changes on disk after launch — configuration management replaced it, a supervisor republished it, Nix activation swapped the goal carrier — the live session keeps acting on the stale version until restart. Nothing tells the agent that a resource it depends on changed.
Goal
A running agent learns, through its normal inbox and DING wake, that one of its declared carriers changed — without restart, without declaration boilerplate, and without waking on noise.
Decisions
Recorded in decision 0008 (settled with the principal over grounded decision requests Q1–Q6 on 2026-08-25):
resyncstream (not a declared stream, not a third record kind): reuses the implemented event ingress — ring dedup, receipt validation, producer-side supersession, DING marker — with exactly one carve-out inresolve_stream. Declaringstream "resync"in a spec is refused.file://URIs and catalog-relative paths resolved against the agent directory (validate_resource_urinow accepts scheme-less relative paths; st2 extension pending canonical Agent Spec adoption). Other schemes are unwatched by design.resources/context|decisions|friction), coalesced (everything else). Nonotifybinding attribute until real volume data justifies the grammar change.Verification
New suite
tests/resync.rs(all green):agent.kdl-> notifies (parent-directory watch survives inode replacement).Full
cargo test: 470 lib + 57 agent-spec + integration suites green. Pre-existing failure verified against baseline:agent_publish::incomplete_apply_marker_blocks_declarations_but_not_the_state_planefails identically on cleanHEAD(1da5809) in this environment.Complexity
One new module (
src/resync.rs, ~450 lines incl. tests), two small seams: the reserved-name carve-out inevent.rs::resolve_streamand relative-URI acceptance inagent-spec. No new dependencies; watching rides the existingnotifybackend and mutation-only filter patterns fromsrc/watch.rs.Concerns
Follow-ups
notifyattribute (blocked on volume data + canonical Agent Spec adoption + How should Nix-managed Agent Specs compose runtime Resource bindings? #305).resync-carrier-changeverifying live-seat behavior end to end (separate PR).References
docs/vrs/06-resync/Posted on behalf of @schickling
agent_identityagent_personaagent_supervisoragent_toolagent_tool_versionagent_runtimetooling_profile