Skip to content

OSAC-1422: Separate session files from repo config to prevent .ai-bot.preserve/ leakage#30

Open
adalton wants to merge 1 commit into
flightctl:mainfrom
adalton:andalton/no-preserve-directory
Open

OSAC-1422: Separate session files from repo config to prevent .ai-bot.preserve/ leakage#30
adalton wants to merge 1 commit into
flightctl:mainfrom
adalton:andalton/no-preserve-directory

Conversation

@adalton

@adalton adalton commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Move bot session files (task.md, issue.md, pr.md, etc.) from .ai-bot/ to .ai-session/, keeping .ai-bot/ purely for repo-owned config
  • Harden commit exclusion to prefix-match .ai-bot and .ai-session (no trailing slash), catching .ai-bot.preserve/, .ai-session.preserve/, and any other variant
  • Update all tests, documentation, and config examples

Problem

The .ai-bot/ directory served dual purposes: repo-owned config files (config.yaml, instructions.md, workflows, container.json) and ephemeral session files (task.md, issue.md, pr.md, session-output.json, etc.). The AI provider running inside the container saw both types mixed together and copied config files to .ai-bot.preserve/, which leaked into PRs because the commit exclusion only matched the exact .ai-bot/ prefix.

Live examples: fulfillment-service PR #676, osac-installer PR #270

After this change

.ai-bot/                    (repo-owned, version-controlled by target repo)
├── config.yaml
├── container.json
├── instructions.md
├── new-ticket-workflow.md
└── feedback-workflow.md

.ai-session/                (ephemeral, never committed)
├── task.md
├── issue.md
├── pr.md
├── session-output.json
├── cli-output.json
├── session.log
├── comment-responses.json
├── session-context.md
└── attachments/

Breaking change

Workflow files in target repos (.ai-bot/new-ticket-workflow.md, .ai-bot/feedback-workflow.md) and profile config overrides that reference .ai-bot/task.md, .ai-bot/pr.md, etc. must be updated to .ai-session/. The imported ai-workflows repo is unaffected (uses .artifacts/ internally).

Test plan

  • go test -race ./... — all tests pass
  • make lint — no new issues (3 pre-existing gosec false positives)
  • Verified no stale .ai-bot/ session-file references remain in production code
  • Verified prefix-match exclusion catches .ai-bot.preserve/, .ai-bot-extra/, .ai-session.preserve/

Resolves OSAC-1422

Assisted-by: Claude noreply@anthropic.com

Packages Affected

Core packages:

  • taskfile/ - Updated exported path constants (IssueFilePath, TaskFilePath, PRDescriptionPath, AttachmentsDirPath, SessionContextPath, CommentResponsesPath) to reference .ai-session/ instead of .ai-bot/
  • executor/ - Updated session file reading/writing across all modules (executor.go, pipeline.go, script.go, session.go) to use .ai-session/ directory; includes test updates
  • services/ - Hardened built-in commit exclusion logic to use prefix matching for both .ai-bot and .ai-session prefixes (catching variants like .ai-bot.preserve/)

No changes to: scanner/, container/, workspace/, jobmanager/, tracker/, projectresolver/, repoconfig/, commentfilter/, recovery/, costtracker/, models/

Execution Pipeline Impact

All three major workflows affected:

  • Ticket processing: Task descriptions moved from .ai-bot/task.md to .ai-session/task.md
  • PR creation: PR descriptions now read from/written to .ai-session/pr.md instead of .ai-bot/pr.md
  • Feedback handling: Comment responses now stored in .ai-session/comment-responses.json; session context in .ai-session/session-context.md

Jira attachments are now downloaded to .ai-session/attachments/ directory.

Configuration and Deployment

Configuration updates:

  • config.example.yaml - Updated workflow instructions to reference .ai-session/ paths
  • services/github.go - Modified builtinExcludes to exclude both .ai-bot and .ai-session using prefix matching (without trailing slash) to catch directory variants and prevent accidental commits of temporary files

Documentation updates:

  • Architecture diagrams, operator guide, and repository configuration documentation all updated to reflect new .ai-session/ paths
  • AGENTS.md - Updated to read PR descriptions from new location

Breaking Changes

Existing workflows in target repositories that reference .ai-bot/task.md, .ai-bot/pr.md, and similar session file paths must be updated to use .ai-session/ equivalents.

….preserve/ leakage

The .ai-bot/ directory served dual purposes: repo-owned config files and
ephemeral session files. The AI provider confused the two, copying config
files to .ai-bot.preserve/ which leaked into PRs because the commit
exclusion only matched the exact .ai-bot/ prefix.

Two fixes:
- Move session files (task.md, issue.md, pr.md, etc.) to .ai-session/,
  keeping .ai-bot/ purely for repo-owned config
- Change commit exclusion to prefix-match .ai-bot and .ai-session (no
  trailing slash), catching .ai-bot.preserve/ and any other variant

Assisted-by: Claude claude-opus-4-6 (1M) <noreply@anthropic.com>
@adalton adalton self-assigned this Jun 15, 2026
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 063b1b58-32f5-4433-884b-49751ec0a994

📥 Commits

Reviewing files that changed from the base of the PR and between bc3660d and 2c5bd25.

📒 Files selected for processing (18)
  • AGENTS.md
  • config.example.yaml
  • docs/architecture.md
  • docs/operator-guide.md
  • docs/repo-configuration.md
  • executor/executor.go
  • executor/pipeline.go
  • executor/pipeline_test.go
  • executor/script.go
  • executor/script_test.go
  • executor/session.go
  • executor/session_test.go
  • services/bot_artifact_test.go
  • services/github.go
  • services/sync_with_remote_test.go
  • taskfile/markdown_writer.go
  • taskfile/markdown_writer_test.go
  • taskfile/writer.go

Walkthrough

All ephemeral AI session artifact paths are renamed from .ai-bot/ to .ai-session/ across six exported path constants in taskfile/writer.go, executor runtime code (script, session, pipeline), the GitHub commit exclusion list in services/github.go, test fixtures, and documentation.

Changes

Session directory rename: .ai-bot → .ai-session

Layer / File(s) Summary
Path constants and Writer interface docs
taskfile/writer.go, taskfile/markdown_writer.go
Six exported constants (IssueFilePath, TaskFilePath, PRDescriptionPath, AttachmentsDirPath, SessionContextPath, CommentResponsesPath) updated from .ai-bot/ to .ai-session/; Writer interface docstrings and top-level package docs aligned to the new directory split.
Executor runtime path updates
executor/script.go, executor/session.go, executor/pipeline.go, executor/executor.go
script.go updates CLI output path constant, tee log target, and taskPrompt; session.go updates sessionOutputPath constant and inline comments; pipeline.go and executor.go update comments only.
GitHub commit exclusion logic
services/github.go
builtinExcludes updated to include both .ai-bot and .ai-session as prefix-matched entries (no trailing slash), with updated comments distinguishing built-in vs import-declared normalization.
Test fixture updates
executor/script_test.go, executor/session_test.go, executor/pipeline_test.go, taskfile/markdown_writer_test.go, services/bot_artifact_test.go, services/sync_with_remote_test.go
Fixture paths, helper functions (writeSessionFile, writeSessionOutput), and assertions updated from .ai-bot/ to .ai-session/; bot_artifact_test.go expands coverage for .ai-bot, .ai-bot.preserve/, and .ai-session prefix exclusion cases.
Documentation
AGENTS.md, config.example.yaml, docs/architecture.md, docs/operator-guide.md, docs/repo-configuration.md
All workflow examples, sequence diagrams, runtime-file contract tables, and instructions updated to reference .ai-session/ paths.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested labels

executor, github-service

Poem

.ai-bot steps aside, makes way for .ai-session new,
Ephemeral files find a home where they always belonged.
Constants, scripts, and docs all march in uniform hue,
A single rename, but every corner has been thronged.
🤖 The bot renames itself — now that's dedication. 📁


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 2 warnings)

Check name Status Explanation Resolution
No-Sensitive-Data-In-Logs ❌ Error Logging statements expose sensitive data: SSH key file paths at Info level (line 342), user email (PII) at Debug level (line 303), and repository URLs with potential credentials (line 286). Remove sshKeyPath from logger.Info call (line 342); redact email from logs; scrub repo URLs before logging; move auth-related logs to Trace/most-verbose level only.
Docstring Coverage ⚠️ Warning Docstring coverage is 28.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Unchecked-Errors ⚠️ Warning executor/session.go readSessionOutput() assigns json.Unmarshal error to blank identifier without comment. Line 254: _ = json.Unmarshal(data, &output) lacks justification for ignoring the parse er... Add a comment explaining why json.Unmarshal error is safe to ignore, e.g., _ = json.Unmarshal(data, &output) // ok if file unparseable, output will be zero-value
✅ Passed checks (10 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title directly and specifically describes the main change: migrating session files from .ai-bot/ to .ai-session/ with the security objective of preventing .ai-bot.preserve/ leakage.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
No-Hardcoded-Secrets ✅ Passed PR contains only path refactoring (.ai-bot/ to .ai-session/). No hardcoded secrets, API keys, tokens, passwords, base64 credentials, or embedded authentication found in code, config, or tests.
No-Weak-Crypto ✅ Passed No weak cryptography patterns (MD5, SHA1, DES, RC4, 3DES, Blowfish, ECB), custom crypto implementations, or insecure token comparisons found. PR contains only path refactoring changes.
No-Injection-Vectors ✅ Passed PR moves session files from .ai-bot/ to .ai-session/ without introducing injection vectors. AIProvider values (only "claude" or "gemini") are validated in Config.validate() before use in buildExecC...
Container-Privileges ✅ Passed No container or K8s manifest files were modified in this PR. Existing container configurations (Dockerfile, docker-compose.yml, podman-compose.yml) run as non-root user with resource limits and no...
Resource-Leaks ✅ Passed PR only changes path constants and documentation comments; no new file operations, HTTP requests, database connections, goroutines, or other unclosed resources introduced.
Ai-Attribution ✅ Passed AI tool (Claude) usage is properly attributed using acceptable "Assisted-by" trailer in both PR description and commit message, not Co-Authored-By.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

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