Semantic Reconciliation

Semantic reconciliation is Toto's system for automatically matching git commits to the tasks you were working on. Instead of manually updating task status after every commit, the reconciliation engine compares each commit against your pending and in-progress tasks and presents matches for confirmation.

The goal: you commit code, and the task board updates itself.

See it in action →


The Concept

After a git commit, the reconciliation engine reads the commit's changed files, message, and diff summary. It compares these against every pending and in-progress task that has metadata. For each commit-task pair, it evaluates multiple signals and produces a confidence score.

Tasks that score above the confident threshold are presented as [MATCH] -- you confirm with a quick "yes" and they're marked done. Tasks that score above the possible threshold but below confident are presented as [MAYBE] -- you decide whether the match is real. Tasks below the possible threshold are skipped entirely.

Nothing is marked done without your confirmation. The engine proposes, you dispose.


Signal Types

The engine evaluates four primary signals for each commit-task pair. Each signal contributes to an overall confidence score.

File Path Overlap

The strongest signal. Every task can predict which files it will modify via the files field in metadata (see Task Metadata). The engine compares these predictions against the commit's actual changed files from git diff --name-only.

A task that predicts app/api/auth_web.py will change, matched against a commit that touches app/api/auth_web.py and app/services/auth_service.py, produces a strong file overlap signal.

The more predicted files overlap with the commit's actual changes, the stronger the signal. Partial overlap (1 of 3 predicted files changed) still contributes, but with less weight than full overlap.

Keyword Match

Technical terms from the task's keywords metadata field are compared against the commit message. Keywords like oauth, session, httponly are specific enough to be meaningful. Keywords like fix or update appear in every commit and provide no signal.

The engine looks for exact keyword matches in the commit message. More matches = stronger signal.

Component Alignment

The task's component field (e.g., auth-middleware) is compared against file paths and the commit message. If the component name or parts of it appear in the paths of changed files, it's a positive signal.

A task with component auth-middleware gets a boost when the commit touches files under app/api/auth* or the commit message mentions "auth".

Scope Match

The task's scope field (backend, frontend, schema, etc.) is cross-checked against the types of files changed in the commit. This acts as a sanity check -- if a task is scoped to backend but the commit only touches .js and .css files, the confidence score is reduced.

Scope mismatches don't disqualify a match, but they lower confidence significantly. A commit that touches both backend and frontend files won't be penalized for either scope.


Confidence Levels

The engine classifies each commit-task pair into one of three categories:

Confident Match [MATCH]

Multiple signals agree. File paths overlap, keywords match, component aligns, scope is consistent. The engine is confident this commit addresses this task.

Presented as:

[MATCH] "Add OAuth middleware" (list: Google OAuth, id: 201)
  Confident match across file paths, keywords, and component signals.

You confirm to mark it done.

Possible Match [MAYBE]

Some signals match but not enough for full confidence. Common scenarios: partial file overlap with no keyword matches, or strong keyword match but no file predictions in the metadata.

Presented as:

[MAYBE] "Write auth tests" (list: Google OAuth, id: 205)
  Possible match — partial file and keyword overlap.

You decide whether to accept or skip.

No Match

Signals don't align. The commit is unrelated to this task. Not shown in the output.


How to Use It

After a Commit

/toto-reconcile --depth 5

Matches the last 5 commits against pending/in-progress tasks. Use this right after committing, or let the post-commit hook trigger it automatically (see Claude Code Integration).

Session Sweep

/toto-reconcile --depth 50

Sweeps the last 50 commits. Use at the start of a session to catch commits from previous sessions that were never reconciled. The session-start hook can automate this.

Scoped Reconciliation

/toto-reconcile --list LIST_ID

Only matches against tasks in a specific list. Useful when you have many lists and want to focus on one feature.


Making Tasks Reconcilable

The quality of reconciliation depends entirely on the quality of task metadata. Here's how each metadata field contributes:

Field Impact on Reconciliation
files Highest impact. Predicted file paths compared against actual changed files.
keywords High impact. Technical terms matched against commit messages.
component Medium impact. Cross-referenced with file paths and messages.
scope Medium impact. Validates that the commit touches the right layer.
intent Low direct impact. Primarily for human context, but helps with title matching.

Tasks with no metadata effectively can't be reconciled. They fall back to title-only keyword matching, which rarely produces results above the confidence threshold.

How to fix bare tasks:

  1. Run /toto-lint to identify tasks missing metadata
  2. Run /toto-enrich --all to auto-generate metadata for bare tasks
  3. Review and approve the generated metadata

See Task Metadata for the full metadata schema and best practices.


Post-Commit Hook

The recommended setup fires reconciliation automatically after every git commit made through Claude Code. Add this to ~/.claude/settings.json:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.command // \"\"' | grep -q '^git commit' && echo '{\"hookSpecificOutput\":{\"hookEventName\":\"PostToolUse\",\"additionalContext\":\"A git commit was just made. Run /toto-reconcile --depth 5 to match this commit against pending tasks.\"}}' || true",
            "timeout": 5
          }
        ]
      }
    ]
  }
}

Note: > The hook only triggers on commits made through Claude Code's Bash tool. Commits in a separate terminal need manual /toto-reconcile or a session-start sweep.


Tips for Better Matches

Write Focused Commits

One task per commit produces the best results. A commit that implements OAuth middleware and also fixes a CSS bug will confuse the engine because it touches files across unrelated tasks.

Use Specific Keywords

Generic keywords (fix, update, refactor) appear in every commit and provide no distinguishing signal. Use technical terms specific to the task: library names, API names, data structures, protocol terms.

Predict File Paths

Even if the file doesn't exist yet, predict where it will be created. The path structure matters more than whether the file exists. app/api/auth_google.py is a useful prediction even if you haven't created it yet -- it tells the engine to watch for commits touching auth-related files in the API layer.

Keep Tasks Granular

A task like "Build the entire auth system" is too broad to match any single commit. Break it into subtasks: "Add OAuth middleware", "Create user model", "Build login redirect". Each subtask can be matched to its corresponding commit.


Limitations


Further Reading