Skip to content

prototype: incubate content-addressed catalog admission - #55

Closed
schickling-assistant wants to merge 1 commit into
compoundingtech:mainfrom
schickling-assistant:2026-07-29-content-addressed-catalog
Closed

prototype: incubate content-addressed catalog admission#55
schickling-assistant wants to merge 1 commit into
compoundingtech:mainfrom
schickling-assistant:2026-07-29-content-addressed-catalog

Conversation

@schickling-assistant

@schickling-assistant schickling-assistant commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Why

The recursive mutable agent.kdl catalog has no transaction boundary for a
fleet assembled by independent static and dynamic publishers. Per-seat file
swaps cannot express an atomic multi-seat change, and declaration provenance is
currently coupled to mutable message/context/status state.

This draft incubates the smallest executable slice of #52. It is a prototype,
not an accepted storage or lifecycle contract.

What

  • add exact-byte content-addressed Agent Spec objects;
  • add parent-linked per-seat ref commits with expected-parent CAS, logical
    manager fencing, and operation replay;
  • add immutable resource-state bindings and SeatAdmission joins;
  • select a complete admission map through one parent-linked catalog-root CAS;
  • split immutable AgentSpec.path from stable mutable AgentSpec.agent_dir;
  • expose an explicitly experimental JSON CLI:
    catalog prepare|stage|admit|publish|head|inspect;
  • add a proposed VRS decision and an implementation experiment record.

Static and dynamic publishers can update their own seats through the same root
protocol. A root transaction records its actor but does not take custody of
foreign seats.

Safety properties exercised

  • prepare imports exact bytes without changing any ref or root;
  • stage changes no catalog-root visibility;
  • stale ref/root parents, ABA, foreign-manager ref movement, malformed digest
    traversal, cross-seat joins, duplicate/reserved/symlinked state roots, and
    corrupt selected objects fail closed;
  • one multi-seat admit becomes visible through one root identity;
  • inspect resolves one captured root rather than mixing root metadata and seats;
  • replay is bound to the original expected parent and exact update.

Validation

  • nix flake check --print-build-logs
    • 157 library tests passed
    • package, help, and completion checks passed
  • cargo test --lib catalog_store::tests: 8 passed
  • cargo test --test catalog_cli: 1 passed
  • scoped Clippy for the library, binary, and catalog CLI test passed with
    -D warnings
  • companion direct-product evals: prepare 5/0, staging/CAS 6/0, root atomicity
    8/0

Deliberate limits

This slice does not integrate the experimental root with resident discovery or
reconciliation. It does not provide a content-addressed render-input bundle,
typed resource contracts, authenticated managers, realization/replacement,
power-loss durability proof, GC, replication, or a daemon control API.
Content-addressed custody assumes the repository's trusted same-user model;
single-FD verify/use sealing remains follow-up hardening.

Companion eval PR: compoundingtech/evals#39.

Closes no issue; incubates #52 and refines #41.

Plain-folder portability target (currently RED)

The acceptance boundary is an ordinary recursively copied or file-synced
catalog folder. That folder alone must support offline inspection and recovery
of the last complete valid activation. Authoring stays as ordinary KDL and
catalog resources; CAS data is additive under the single catalog-owned
.st2/catalog-v1 directory, never under per-agent .st2 directories.

The current prototype does not meet this target. Its mutable
.st2/catalog-v1/root can arrive before its referenced object closure, and
inspect then fails on missing or corrupt selected objects instead of falling
back to the previous complete activation. The current head is therefore
incubation evidence, not an accepted LKG or portability implementation.

The smallest next slice is read-only inspection/activation fallback: publish
immutable versioned activation records, select the newest complete valid
closure, and fall back to an older complete valid activation. It must not
broaden resident discovery or reconciliation.

Pre-registered adversarial gates

These model-free gates are RED requirements before code is broadened:

  1. randomized object and activation/head arrival order;
  2. interrupted ordinary copy after every file boundary;
  3. missing or corrupt objects and missing or corrupt newest head/activation;
  4. offline restart and inspection from only the copied catalog folder; and
  5. atomic old-or-new activation: every intermediate prefix preserves LKG until
    the complete new closure is valid, then selects it without a mixed view.

The slice cannot depend on a database, daemon, reachable peer, consensus,
online service, or special copy order. It includes no physical GC or remote
delete propagation. Future GC must preserve selected/fallback closures and
leave a standalone ordinary folder.

Posted on behalf of @schickling
field value
agent_name co2-pine
agent_session_id cdd15622-c01a-4731-bbfe-ab8cce0cad54
agent_tool Codex CLI
agent_tool_version 0.145.0
agent_runtime Codex CLI 0.145.0
agent_model unknown
runtime_profile /nix/store/ph8rlhdj25mg71v81jsfzy6dq4xpcs9m-coding-agent-runtime-profile/share/coding-agents/profile.json
skills_manifest /nix/store/lsykz8x5481xrpbgk280xh3pypk1c5jy-agent-skills-corpus/share/agent-skills/manifest.json
worktree st2/schickling-assistant/2026-07-29-content-addressed-catalog
machine dev3
tooling_profile dotfiles@3649b53

agent-session-id: cdd15622-c01a-4731-bbfe-ab8cce0cad54
agent-tool: Codex CLI
agent-tool-version: 0.145.0
agent-model: unknown
agent-runtime-profile: /nix/store/ph8rlhdj25mg71v81jsfzy6dq4xpcs9m-coding-agent-runtime-profile/share/coding-agents/profile.json
agent-skills-manifest: /nix/store/lsykz8x5481xrpbgk280xh3pypk1c5jy-agent-skills-corpus/share/agent-skills/manifest.json
tooling-profile: dotfiles@3649b53

myobie commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

@schickling-assistant — owner handoff for the existing fork branch only
schickling-assistant:2026-07-29-content-addressed-catalog (please do not
replace it with a second implementation branch):

  1. Refresh the branch onto merged st2 main 58c48515d6ef3ebe459302b6e90b16e64b149f51.
  2. Resolve the four known content conflicts only:
    • crates/agent-spec/src/spec.rs
    • src/lib.rs
    • src/run.rs
    • tests/reconcile.rs
  3. Port the prototype to the current agent-spec crate boundary, direct-argv
    task/launch model, and PR Issue #29: targeted task reconciliation #50 selected-reconcile/hook signatures without
    broadening resident reconciliation.
  4. Implement only the read-only complete-activation fallback slice described
    above: immutable versioned activation records; newest complete valid closure
    selection; prior complete activation fallback.
  5. Keep authoring as ordinary KDL/resources and implementation data under the
    one catalog-owned .st2/catalog-v1; add no database, daemon, service, peer,
    consensus, per-agent .st2, physical deletion GC, rollout, or adoption.
  6. Make the five pre-registered adversarial gates executable and return the
    exact refreshed head plus commands/results for each gate.

Please keep PR #55 DRAFT. No merge or adoption is authorized.

@schickling-assistant

Copy link
Copy Markdown
Contributor Author

Two questions before starting items 1 and 2, because current main interacts with them in ways the handoff could not have anticipated on 07-30.

To find out what the refresh actually involves, I rebased the existing fork branch onto current main (b868a07) rather than the pinned 58c48515, which is now an ancestor of main. That was to discover the conflict set only. Nothing has been pushed, nothing has been resolved, the rebase is aborted, and the fork branch is untouched at 16ee7eb. The PR remains DRAFT and this is not a request to merge or adopt anything.

The conflict set against current main:

handoff item 2 named what the rebase produced
crates/agent-spec/src/spec.rs src/spec.rsmodify/delete
src/lib.rs src/lib.rs
src/run.rs src/run.rs
tests/reconcile.rs tests/reconcile.rs
src/message.rs — not named in the handoff

Question 1 — spec.rs. It comes through as modify/delete: main deleted src/spec.rs in 14fe7dc (refactor: extract the agent-spec crate, #54) and the file now lives at crates/agent-spec/src/spec.rs, which is the path item 2 names. Since the branch still edits the old path, there is no textual resolution — the change has to be carried across the crate boundary, which is item 3 rather than item 2.

Should item 2 be understood to include that port for spec.rs, or would you rather spec.rs be left alone until item 3 is scoped?

Question 2 — src/message.rs. This file is not in the handoff's list and its conflict is substantial (a 294-line hunk and a 24-line hunk). The smaller hunk is the one I want your read on: main's side calls crate::catalog_transaction::retained_dir_path in seven places, and the branch contains no occurrences of it — the prototype predates the function.

Resolving that hunk toward the branch would remove those call sites, and because the retained-directory path resolves through /proc/self/fd on Linux, the result would compile and the suite would pass while the macOS behaviour retained_dir_path exists to provide is gone. I would rather not guess at the intended shape here.

How would you like src/message.rs handled — is carrying the branch's changes onto main's current version of that file in scope for item 2, or does it belong with the porting work?

Happy to proceed on items 1 and 2 as soon as these two are settled. The remaining three conflicts (src/lib.rs, src/run.rs, tests/reconcile.rs) match the handoff exactly and I have no questions about those.

Posted on behalf of @schickling
field value
agent_name unknown
agent_tool Claude Code
agent_tool_version 2.1.220
agent_runtime Claude Code 2.1.220
agent_session_lookup unavailable
tooling_profile dotfiles@unknown-dirty

@schickling schickling added area:agent-spec Agent Spec format, parsing, and the agent-spec crate · Set: manual area:catalog Catalog structure, declarations, transactions, and admission · Set: manual origin:agent Filed or primarily produced by an AI agent · Set: manual type:feature New user-visible or system capability · Set: manual labels Aug 18, 2026
@schickling-assistant

Copy link
Copy Markdown
Contributor Author

Superseded by current transactional publication, desired-input digest, mediated authoring, and authoritative graph validation. The prototype's second catalog/CAS authority is no longer applicable.

Posted on behalf of @schickling
field value
agent_identity dev3.direct.omp.jmg9x29x
session dev3.jmg9x29x
agent_persona generalist
agent_supervisor unavailable
agent_tool OMP
agent_tool_version 18.0.11
agent_runtime OMP 18.0.11
tooling_profile dotfiles@2161b9c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:agent-spec Agent Spec format, parsing, and the agent-spec crate · Set: manual area:catalog Catalog structure, declarations, transactions, and admission · Set: manual origin:agent Filed or primarily produced by an AI agent · Set: manual type:feature New user-visible or system capability · Set: manual

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants