Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions internal/cli/orient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,10 @@ func setupCLIDaybook(t *testing.T, notes ...cliNote) (string, string) {
if writer == "" {
t.Fatalf("publisher writer missing in %s", writers)
}
code, body, _ = runMain(t, "", "get", "notes/missing.md", "--cortex", "vault")
if code != 1 || body["error"] != "not_found" {
t.Fatalf("missing get: exit=%d body=%v", code, body)
}
return human, writer
}

Expand Down
16 changes: 0 additions & 16 deletions internal/kernel/clean_writer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@ func (f *fixture) noOriginClone(t *testing.T, name string) string {
return dir
}

// Proof 15 (sole publisher): the kernel-owned writer clone is the sole
// publisher for daybook cortices. Writes land, commit, and push from
// the writer clone without touching the registered human checkout,
// even when the human checkout carries uncommitted edits, staged work,
// or a dirty heartbeat. Reads immediately resolve from the publisher clone.
func TestProof15SolePublisherIsolatesFromHumanCheckout(t *testing.T) {
f := newFixture(t)

Expand Down Expand Up @@ -88,8 +83,6 @@ func TestProof15SolePublisherIsolatesFromHumanCheckout(t *testing.T) {
}
}

// A LEFTOVER-DIRTY PUBLISHER clone must abort the write at the publisher-
// root scan — the publisher repository must always be clean.
func TestDirtyPublisherAborts(t *testing.T) {
f := newFixture(t)

Expand Down Expand Up @@ -118,8 +111,6 @@ func TestDirtyPublisherAborts(t *testing.T) {
}
}

// Proof 16: publisher pins the registered checkout's actual tracked branch
// (e.g. feature-vault), not the remote's default branch (master).
func TestPublisherPinsNonDefaultTrackedBranch(t *testing.T) {
f := newFixture(t)
// Create and checkout non-default branch on hosta
Expand Down Expand Up @@ -149,8 +140,6 @@ func TestPublisherPinsNonDefaultTrackedBranch(t *testing.T) {
}
}

// Proof 17: Get on a freshly registered cortex provisions the publisher clone
// and reads clean committed state, never uncommitted human dirt on c.Path.
func TestProof17FreshRegistrationReadsCommittedStateNotHumanDirt(t *testing.T) {
testConfigEnv(t)
base := t.TempDir()
Expand Down Expand Up @@ -199,8 +188,6 @@ func TestProof17FreshRegistrationReadsCommittedStateNotHumanDirt(t *testing.T) {
}
}

// Proof 18: provisioning failure fails closed — Get/Log/Lint return cortex_unavailable,
// never silently falling back to uncommitted bytes on c.Path.
func TestProof18ProvisioningFailureFailsClosed(t *testing.T) {
testConfigEnv(t)
base := t.TempDir()
Expand Down Expand Up @@ -233,9 +220,6 @@ func TestProof18ProvisioningFailureFailsClosed(t *testing.T) {
}
}

// Proof 19: completely missing origin remote on a daybook cortex fails closed
// across reads and writes — Put returns writer_unavailable; Get/Log/Lint return
// cortex_unavailable; zero fallback to c.Path.
func TestProof19MissingOriginFailsClosedAcrossReadsAndWrites(t *testing.T) {
testConfigEnv(t)
base := t.TempDir()
Expand Down
10 changes: 5 additions & 5 deletions internal/kernel/mcp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import (
"github.com/modelcontextprotocol/go-sdk/mcp"
)

// binPath is the built exocortex binary used for the MCP stdio
// round-trip; TestMain builds it once for the package.
var binPath string

func TestMain(m *testing.M) {
Expand All @@ -35,8 +33,6 @@ func TestMain(m *testing.M) {
os.Exit(code)
}

// Proof 7: MCP face round-trip — get → put(expectedRevision) → get
// bumps the revision and preserves the payload apart from the stamp.
func TestProof7MCPRoundTrip(t *testing.T) {
f := newFixture(t)
ctx := context.Background()
Expand Down Expand Up @@ -84,6 +80,11 @@ func TestProof7MCPRoundTrip(t *testing.T) {
t.Fatalf("get mismatch: isErr=%v body=%v", isErr, got)
}

missing, isErr := call("exocortex_get", map[string]any{"path": "notes/missing.md", "cortex": "hosta"})
if !isErr || missing["error"] != "not_found" {
t.Fatalf("missing get: isErr=%v body=%v", isErr, missing)
}

updated := mkNote("note", "mcp roundtrip v2")
body, isErr = call("exocortex_put", map[string]any{
"path": "notes/mcp.md", "content": updated,
Expand All @@ -105,7 +106,6 @@ func TestProof7MCPRoundTrip(t *testing.T) {
t.Fatalf("provenance stamp missing:\n%s", disk)
}

// Stale expectedRevision surfaces the pinned conflict as an error result.
body, isErr = call("exocortex_put", map[string]any{
"path": "notes/mcp.md", "content": updated,
"expectedRevision": rev1, "cortex": "hosta",
Expand Down
9 changes: 6 additions & 3 deletions internal/kernel/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ func (s readSnapshot) read(path string) ([]byte, error) {
if s.sha != "" {
raw, err := git(s.repo, "show", s.sha+":"+path)
if err != nil {
if tree, treeErr := git(s.repo, "ls-tree", "-z", s.sha, "--", path); treeErr == nil && tree == "" {

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 Treat the ls-tree probe as a literal path

For legal paths beginning with Git pathspec magic, this is not an exact lookup. For example, if notes/existing.md exists but the requested literal path :(literal)notes/existing.md does not, git show fails while git ls-tree ... -- ":(literal)notes/existing.md" resolves the magic and returns the other file; Get consequently reports cortex_unavailable instead of not_found. Force literal pathspec handling or escape the lookup path before classifying the failure.

AGENTS.md reference: AGENTS.md:L48-L49

Useful? React with 👍 / 👎.

return nil, fs.ErrNotExist
}
return nil, err
}
return []byte(raw), nil
Expand Down Expand Up @@ -363,13 +366,13 @@ func conflictForRequest(source *Conflict, operation, path string) *Conflict {
}

func snapshotReadConflict(c *Cortex, operation, path string, err error) *Conflict {
if c.VCS == "daybook" {
return snapshotUnavailable(operation, path, err)
}
if errors.Is(err, fs.ErrNotExist) {
return conflict("not_found", operation, path,
"check the path; search the cortex to locate the note", nil)
}
if c.VCS == "daybook" {
return snapshotUnavailable(operation, path, err)
}
return conflict("read_failed", operation, path, "fix filesystem access and retry",
map[string]any{"detail": err.Error()})
}
Expand Down
13 changes: 13 additions & 0 deletions internal/kernel/read_refresh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package kernel

import (
"context"
"errors"
"io/fs"
"os"
"os/exec"
"path/filepath"
Expand Down Expand Up @@ -106,6 +108,17 @@ func TestReadFailsWithoutUpstream(t *testing.T) {
}
}

func TestGetClassifiesMissingCommittedPath(t *testing.T) {
f := newFixture(t)
got, conf := Get(f.cs, "hosta", "notes/missing.md")
if got != nil || conf == nil || conf.Code != "not_found" || conf.Path != "notes/missing.md" {
t.Fatalf("got=%+v conflict=%#v", got, conf)
}
if _, err := (readSnapshot{repo: mustEffectiveRoot(&f.cs[0]), sha: "missing-commit"}).read("README.md"); errors.Is(err, fs.ErrNotExist) {
t.Fatalf("invalid snapshot classified as missing path: %v", err)
}
}

func TestGetManyDoesNotMixRevisionsAfterOriginAdvance(t *testing.T) {
f := newFixture(t)
notes := []struct {
Expand Down
Loading