Skip to content

fix(app): app helpers use a cell chat's own folder, and keep its earlier receipts - #1970

Merged
AbirAbbas merged 5 commits into
app/v3from
fix/app-cell-folders
Oct 26, 2026
Merged

AbirAbbas merged 5 commits into
app/v3from
fix/app-cell-folders

Conversation

@AbirAbbas

Copy link
Copy Markdown
Collaborator

What was wrong

A cell-backed chat keeps its journal at <chat>/.cell/transcript.jsonl. App helpers in cmd/codeaf/app*.go took the conversation folder as filepath.Dir(transcript), which is <chat>/.cell for such a chat. That pointed 22 helpers at the wrong folder, so the desktop could:

  • refuse valid job output ("this process's output is not in its conversation's logs folder"), because the managed log anchor became <chat>/.cell/logs/jobs/N.log while logs live at <chat>/logs/jobs/N.log;
  • scope media to session id .cell with the wrong work root;
  • build deliverable and task-branch Places rooted at .cell, reading the wrong work and trees;
  • read presence and close-recovery claims from the wrong file.

What changed

  • Every app helper that needs the conversation folder now uses session.DirOf, which knows both layouts and keeps the old fallback for an unrecognised transcript name.
  • App receipts (app-footers.json) that earlier builds wrote under <chat>/.cell/ stay readable: reads merge both locations by entry id, new receipts are written at the chat root, and the old file is left in place.
  • internal/session/task_branches.go reads task records through Place.Tasks() / Place.truth(), so a Place rooted at a cell chat finds .cell/tasks.json and .cell/.deleted-tasks.json. Shared code: a terminal caller holding such a Place gains the same correction.
  • appAgentID is untouched. The .cell agent-id collision is fixed separately in fix(app): keep cell chat identities separate #1965; the two do not conflict.

How it was checked

New tests over a real cell folder (made with cell.CreateIn, as app minting does), a legacy folder and a flat path: process log anchor, media scope, deliverables, presence, receipts (including an upgrade from the old receipt location, two writes, no duplicates, unreadable input), blank-chat reaping, take-back, archive/reopen, close metadata, reference snapshots, deliverable changes, task branches and tombstones. The real land is refused on GitHub's runners because their system git config runs a filter (the same reason this repo's land tests fail there); the folder test asserts that typed refusal and skips only the nested land step in that case.

CI was dispatched by hand (it does not trigger for PRs into app/v3) and compared with a baseline Full check of app/v3 at the same base, 575a390 (run 40372386102), which already fails 76 tests. The only failures not in that baseline were the land test above (now handled) and TestAppABlankAgentIsNeitherListedNorKept, which also fails in the baseline PR gate (run 40372392409) with the same message. All internal/session failures in this branch's PR gate also fail in the baseline Full check; they ran here only because task_branches.go is in this diff.


🤖 Generated with Claude Code

@AbirAbbas

Copy link
Copy Markdown
Collaborator Author

Final CI on 4134ea5 (dispatched by hand; CI does not trigger for PRs into app/v3), compared with app/v3 575a390 (Full check run 40372386102, PR gate run 40372392409):

  • PR gate (run 40382758564): every touched-package test passes. The only red is the light gate's lint in internal/factory/run/chatstage.go, which this branch does not touch and which the baseline also fails.
  • Full check (run 40381782556): beyond the baseline's failures, four tests failed once: three with only TempDir RemoveAll cleanup: directory not empty and one asynchronous task-source report, all on code paths this branch does not change. TestAppFolderBranchLandFiles now checks the folder records and skips only the nested land when the machine's git config runs a filter (GitHub's system git-lfs), as the land refuses by design.

🤖 Generated with Claude Code

@AbirAbbas

Copy link
Copy Markdown
Collaborator Author

Correction to the CI note above: a hand-dispatched PR gate with no PR trigger tests only the packages the branch's last commit touched (HEAD~1), and 4134ea5 only renames the change entry, so run 40382758564 skipped the package legs. It is not evidence for the code. The evidence is the Full check, which runs every package: run 40381782556 on cbc6106 (code identical to the head) differs from the app/v3 baseline Full check (run 40372386102) only by the four failures listed above, all on code paths this branch does not change. Earlier PR gates on the code commits (f64b2ae, f62b91f, 2aa605f) covered cmd/codeaf and internal/session; their only branch-caused failure was the land test, since handled.

🤖 Generated with Claude Code

AbirAbbas and others added 5 commits October 26, 2026 17:03
Use session.DirOf when app helpers need a conversation folder. Cell journals
under .cell now resolve to the owning chat for managed logs, media scope,
deliverables, task working copies, presence, receipts and lifecycle helpers.
Read existing cell receipts from both locations and merge by entry id when
saving new receipts at the chat root. Retain the old file, receipt anchors
and fields, and refuse writes when either input cannot be read. Keep task,
process and deletion records visible at their existing truth paths for lazy
recovery, branch listings and confirmed branch lands.

Preserve the legacy and unrecognized-transcript fallback, wire fields and
the separately owned appAgentID function. Keep cleanup allowlists intact.
Add real-cell, legacy and flat-path regressions for upgrades, readers and
destructive file boundaries, and an unreleased change entry. task_branches
now reads task records through Place.Tasks(), so a Place rooted at a cell
chat finds .cell/tasks.json (a terminal caller with such a Place gains this too).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…config

A land refuses a repository whose git config runs a filter program, and the
CI runner's global config carries one, so TestAppFolderBranchLandFiles was
refused in every layout. Point the test at no global or system config, as
appfilediff_test does.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The land strips every GIT_* variable from the git it runs, so
GIT_CONFIG_GLOBAL never reached it and the runner's ~/.gitconfig filter still
refused the land. Point HOME and XDG_CONFIG_HOME at a temporary home whose
only config is a commit identity.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Keep cell, legacy and flat task-record and tombstone checks running when
the production land planner sees a filter in the machine's git config.
Assert the typed filter refusal, then skip only the nested land step.
Preserve confirmation and checkout-file checks on hosts without filters.

Check deleted-task planning and unchanged chat files and checkout HEAD
before any skip. Remove ineffective GIT_CONFIG_* overrides: landEnv strips
them, so they cannot suppress the runner's system filter. Leave the
production refusal and all other land policy unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@AbirAbbas
AbirAbbas force-pushed the fix/app-cell-folders branch from 4134ea5 to d6d8584 Compare October 26, 2026 21:03
@AbirAbbas
AbirAbbas marked this pull request as ready for review October 26, 2026 21:29
@AbirAbbas
AbirAbbas merged commit a760dfe into app/v3 Oct 26, 2026
1 check passed
@AbirAbbas
AbirAbbas deleted the fix/app-cell-folders branch October 26, 2026 21:29
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