Skip to content

Make Swift and Rust peer implementation lanes - #15

Merged
AstroQore merged 2 commits into
mainfrom
refactor/symmetric-implementations
Aug 31, 2026
Merged

Make Swift and Rust peer implementation lanes#15
AstroQore merged 2 commits into
mainfrom
refactor/symmetric-implementations

Conversation

@AstroQore

Copy link
Copy Markdown
Owner

Summary

The Rust crate landed as crates/ beside the Swift Sources/, which reads as a primary implementation with an attachment. It is not one — the two lanes implement the same session-reading semantics for different hosts, and neither is generated from the other. This makes the layout say that.

Package.swift                 SwiftPM entry point       (unchanged location)
Cargo.toml                    Cargo workspace root      (unchanged location)
contracts/storage/            Facts both lanes are tested against
implementations/swift/        Sources/ + Tests/
implementations/rust/         crates/

No consumer changes anything. Both manifests stay at the repository root and reach into implementations/ with explicit paths, so the git URL, the exact: pin, import AgentSessionKit, and both product names are unaffected. Verified against the two dependents (vibe-bar, auspex). The one real move is for anyone depending on the Rust crate by path rather than by git: crates/implementations/rust/crates/.

contracts/

Peers that are not generated from each other need somewhere to agree. The first fact that qualifies is the session index schema, which until now lived only inside the Swift writer while the Rust reader asserted a matching version number by hand — exactly the shape that drifts silently.

contracts/storage/session-index-v5.sql is now the canonical DDL, and each lane has a test that reads it:

  • SessionIndexContractTests (Swift) — the writer creates exactly the objects the contract names, compared as sorted object names so formatting differences do not fail the build but a real addition or removal does.
  • index::contract_tests (Rust) — builds a database straight from the file, opens it with the reader, and checks the enforced user_version equals the one the contract declares.

Verified by deliberately adding a table to the contract: Swift fails, revert makes it pass.

I did not create the empty schemas/, fixtures/, vectors/, or tools/ directories from the sketch, or a second agent-session-contract crate. There is nothing to put in them yet, and an empty abstraction is the thing this change is trying to remove.

A real break the move caught

AgentSessionKitInfoTests resolved the repository root by walking three directories up from #filePath; it is five now. It had been failing as an XCTest case while the swift-testing summary still reported everything green — worth knowing independently of this refactor.

Version

0.7.0 — structural change plus the new contract lane. AgentSessionKitInfo.version and the Rust crate version both track it, as AgentSessionKitInfoTests requires.

Test plan

  • swift test: 618 swift-testing + all XCTest cases green, including the two new contract tests.
  • cargo test --workspace: 73 green (71 + 2 new contract tests).
  • cargo clippy --workspace --all-targets -- -D warnings and cargo fmt --check: clean.
  • Both lane workflows now scope to their own paths plus contracts/, so a contract change runs both.

🤖 Generated with Claude Code

The Rust crate arrived as crates/ beside the Swift Sources/, which read as
a primary implementation with an attachment. It is not one: the two lanes
implement the same session-reading semantics for different hosts, and
neither is generated from the other.

Sources/ and Tests/ move to implementations/swift/, crates/ moves to
implementations/rust/. Both manifests stay at the repository root and reach
in with explicit paths, so no consumer of either language changes anything.

Peers that are not generated from each other need somewhere to agree, so
contracts/ arrives with the first fact that qualifies: the session index
DDL and its user_version, which until now existed only inside the Swift
writer while the Rust reader asserted a matching number by hand. Each lane
now has a test that reads that file -- Swift checks it creates exactly
those objects, Rust builds a database from it and opens it -- so a schema
change on one side alone fails CI instead of silently diverging.

The move also caught a real break: AgentSessionKitInfoTests walked three
directories up from #filePath to find CHANGELOG.md, which is five now. It
had been failing as an XCTest case while the swift-testing summary line
still said everything passed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 31, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-08-31T07:50:35.464037Z 285098c New commits
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8bbef3314a

ℹ️ 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".

Comment thread Package.swift
Comment thread implementations/swift/Tests/AgentSessionKitTests/SessionIndexContractTests.swift Outdated
Two findings from review, both real.

release.yml read the version constant from Sources/AgentSessionKit/, which
the move emptied. Tagging 0.7.0 would have failed at the version check --
the one job that must not break on the commit that renames things.
RELEASING.md named the same stale path.

The contract test compared only created object names, so a changed column
type, constraint, index expression, FTS tokenizer, or trigger body passed
while the two lanes silently disagreed. It now compares whole normalised
CREATE statements; only whitespace and IF NOT EXISTS are normalised away,
since those differ between a file run once and a writer that re-runs on
every open. Verified by flipping the FTS tokenizer in the contract alone:
the old comparison missed it, this one fails.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@AstroQore
AstroQore merged commit 443ed10 into main Aug 31, 2026
4 checks passed
@AstroQore
AstroQore deleted the refactor/symmetric-implementations branch August 31, 2026 07:47

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 285098c280

ℹ️ 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".

echo "Tag: ${TAG}"

INFO="Sources/AgentSessionKit/AgentSessionKitInfo.swift"
INFO="implementations/swift/Sources/AgentSessionKit/AgentSessionKitInfo.swift"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Verify the Rust crate version before publishing

When a later shared release updates the Swift constant and changelog but accidentally leaves the Rust manifest behind, this job still publishes because it validates only AgentSessionKitInfo.version and runs only Swift commands. Rust consumers fetching that tag then receive a crate whose package version disagrees with the release, so the release check should also compare implementations/rust/crates/agent-session-core/Cargo.toml with TAG before publishing.

AGENTS.md reference: AGENTS.md:L74-L79

Useful? React with 👍 / 👎.

Comment thread README.md
searchable index, and a local MCP transport.

No third-party dependencies. Foundation, Darwin, and the system SQLite.
No third-party dependencies in either lane beyond the system SQLite.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Correct the dependency-free claim

This claim is false for the newly documented Rust lane: its manifest depends on rusqlite, serde, serde_json, and thiserror, while rusqlite enables bundled SQLite rather than using only the system library. This can mislead consumers assessing binary size, licensing, or supply-chain exposure; scope the statement to Swift or document the Rust dependencies accurately.

Useful? React with 👍 / 👎.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant