Skip to content

Add actor-aware git identities with HTTPS credential override#6

Open
yashturkar wants to merge 5 commits into
mainfrom
feat/actor-aware-git-identities
Open

Add actor-aware git identities with HTTPS credential override#6
yashturkar wants to merge 5 commits into
mainfrom
feat/actor-aware-git-identities

Conversation

@yashturkar

@yashturkar yashturkar commented Mar 12, 2026

Copy link
Copy Markdown
Owner

Summary

  • Separate USER (human) and AGENT (API) git identities so commits/pushes are attributed to distinct accounts
  • Add GIT_AGENT_HTTPS_TOKEN config that uses url.insteadOf to override system credential helpers (osxkeychain, store) for agent pushes
  • Add GITHUB_AGENT_TOKEN for agent-specific GitHub API calls (PR creation)
  • Propagate GitActor through all git_service, git_batcher, github_service, autosave, and route layers
  • Add TODO for auth-based actor identity (currently caller-declared via source param) in SECURITY.md, product spec, and tech-debt tracker
  • Fix missing docs/exec-plans/active/ directory required by docs_lint

Test plan

  • source=human write commits to main as USER identity and pushes with user credentials
  • source=api write commits to kb-api/* branch as AGENT identity, pushes with agent token, creates PR as agent
  • git log shows distinct author/committer for each actor
  • All 43 relevant tests pass
  • docs_lint.py passes
  • Verify PR on GitHub shows agent account as author

🤖 Generated with Claude Code - skipped over my docs and tests despite telling it, then switched to codex

Separate USER (human) and AGENT (API) git identities so commits and
pushes are attributed to the correct account.  Each actor gets its own
author/committer name+email, optional SSH command, and—new in this
PR—an optional HTTPS token that overrides system credential helpers
via git url.insteadOf rewriting.

- Add GitActor type and propagate actor through all git_service calls
- Add _actor_env() to inject per-actor GIT_AUTHOR_*, GIT_COMMITTER_*,
  GIT_SSH_COMMAND, and url.insteadOf env vars
- Add GITHUB_AGENT_TOKEN for agent-specific PR creation
- Route source=human writes with USER_ACTOR, source=api with AGENT_ACTOR
- Update autosave worker to use USER_ACTOR for pull/commit/push
- Add GIT_AGENT_HTTPS_TOKEN config for HTTPS push auth separation
- Update tests for actor propagation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@yashturkar yashturkar requested a review from yashomdighe March 12, 2026 04:11
Flag that USER vs AGENT identity is currently caller-declared via
the source query param and should be derived from authentication.
Added to SECURITY.md, kb-server product spec, and tech-debt tracker.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@yashturkar yashturkar self-assigned this Mar 12, 2026
yashturkar and others added 3 commits March 11, 2026 22:24
The docs_lint script expects this directory to exist.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The generator used local time, causing date mismatches when CI
runs in UTC. Switch to datetime.now(timezone.utc).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@yashturkar yashturkar linked an issue Mar 12, 2026 that may be closed by this pull request
Comment on lines +17 to +19
GitActor = Literal["user", "agent"]
USER_ACTOR: GitActor = "user"
AGENT_ACTOR: GitActor = "agent"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This may be cleaner as an enum. The current pattern duplicates the allowed values by defining both a Literal alias and named constants. An enum would centralize the valid options in one place and make usage clearer.

Comment on lines +552 to +557
def push_branch(
branch: str,
remote: str | None = None,
retries: int = 2,
actor: GitActor | None = None,
) -> None:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The general push also has branch and remote args. Why is this needed?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Incase you don't wanna push to master/main ..?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

We haven't exposed that to the config though

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This relates to my other comment but it seems push is only called by autosave for user. We can just one with defaults to be main/master.

Comment on lines +22 to +25
def _token_for_actor(actor: GitActor = AGENT_ACTOR) -> str:
if actor == AGENT_ACTOR and settings.github_agent_token:
return settings.github_agent_token
return settings.github_token

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Might be safer to explicitly check for if it also a user actor instead operating under the assumption of anything not agent is user. This might also be affected by moving to the enum

remote: str | None = None,
branch: str | None = None,
retries: int = 2,
actor: GitActor | None = None,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We can also enforce constraints here. It seems only autosave uses this function to push user edits. We can only allow user edits here.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Agreed, even better if we entirely yeet autosave and just keep vault-sync which uses the API

@yashturkar

Copy link
Copy Markdown
Owner Author

@copilot address @yashomdighe 's comments and update this PR with the fix

Copilot AI commented Mar 24, 2026

Copy link
Copy Markdown

@yashturkar I've opened a new pull request, #14, to work on those changes. Once the pull request is ready, I'll request review from you.

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.

Support separate git identities for human vs agent writes

3 participants