Skip to content

Load the committed Project Direction; treat uncommitted triad files as drafts #135

Closed

Description

@lukemaj

Outcome

Agents always load the committed Project Direction. An uncommitted or edited local VISION.md, MISSION.md or OBJECTIVE.md is reported as a draft and never loaded as the current direction.

Problem Statement

bin/project-direction reads the triad from the working tree and only compares committed HEAD with a known upstream. Uncommitted files are never detected. In toolboxmd/t3code, untracked fleet-pane drafts superseded by a merged direction PR (toolboxmd/chromeria#5) were loaded as the direction in every session for days: the hook reported potentially_stale, but context.md says unknown or stale evidence "never suppresses the local triad", so agents planned against the wrong Objective.

Solution

  1. Rule (context.md): the committed triad on the intended base is the Project Direction. Uncommitted or modified triad files in a checkout are drafts. A draft is proposed through the Project Direction procedure (user confirmation, then a PR) or discarded; overwriting a stale local copy is safe because Git keeps every committed state.
  2. Loader (bin/project-direction inspect and the hooks that call it): per file, compare the working tree with HEAD.
    • Modified or untracked while HEAD has the file: inject the HEAD version and report the draft (status such as uncommitted_draft, with the paths).
    • Known upstream ahead and changing the triad: inject the upstream committed version from local refs (no network, no checkout mutation) and keep reporting it.
    • No committed triad anywhere (new project): inject the drafts, marked as drafts, so initialization still works.

Acceptance criteria

  • context.md states the committed-direction rule and the draft lifecycle.
  • The loader injects committed content for modified and untracked files and reports them as drafts.
  • The loader injects the upstream committed triad when known upstream is ahead and changes it, using local refs only.
  • New-project initialization with only uncommitted drafts still works, marked as drafts.
  • Every host integration that consumes the loader (Claude, Codex, OpenCode, Grok hooks) gets the new behaviour.
  • Tests cover clean, modified, untracked, upstream-ahead and never-committed cases.

Non-goals

  • Network fetches or checkout mutation by loaders.
  • Changing how direction is confirmed or edited.

Blockers

None.

Required proof

  • Repository test suite and release-check pass; independent review with a review/independent success status on the exact head.
  • A live run of the loader in a scratch repo for each case, output recorded on the PR.

Activity

  1. lukemaj commented on Sep 27, 2026

    @lukemaj
    ContributorAuthor

    Handoff: implementation in PR #136, head 824ba434c9999586df284d3fa293f26e96eb8705 on fix/135-committed-direction. Not merged (merging releases 12.5.0).

    • Loader: bin/project-direction injects each triad file from HEAD, or from the local upstream ref when known upstream is ahead and changes it; checkout copies that differ from HEAD are reported in drafts; a file with no committed version is injected with source draft. All hosts (Claude, Codex, OpenCode, Grok) call this one loader.
    • Payload: statuses unchanged; new files[].source and optional drafts.
    • Rule: context.md states the committed-direction rule and the draft lifecycle; README paragraph aligned.
    • Proof: 298 repo tests OK, versionctl release-check OK (v12.5.0), version-check CI green, live scratch-repo runs for all five cases in feat: load the committed Project Direction; treat uncommitted triad files as drafts #136 (comment).
    • Remaining gate: review/independent success on the exact head, posted by an independent reviewer; then human merge approval.
  2. added a commit that references this issue on Sep 27, 2026
    af13cd7
  3. lukemaj commented on Sep 27, 2026

    @lukemaj
    ContributorAuthor

    Handoff update: review findings from #136 (comment) fixed. PR #136 head is now af13cd7d5c9bb11eb25889f5e5e4eb5841a77376 (single squashed commit, v12.5.0). Not merged.

    • Upstream files chosen by merge-base diff (HEAD...upstream), so a newer local committed file keeps source: head in a diverged checkout.
    • Committed in-tree symlinks resolve to their target text again (cat-file --batch --follow-symlinks), with no draft reported.
    • A file that upstream deleted falls back to HEAD instead of source: draft.
    • GLOSSARY "Potentially stale Project Direction" and project-direction step 1 reworded; README paragraph cut.
    • Proof: 301 tests OK, release-check OK, version-check CI green, live runs for the new cases in feat: load the committed Project Direction; treat uncommitted triad files as drafts #136 (comment).
    • Remaining gate: review/independent success on af13cd7, then human merge approval.
  4. added a commit that references this issue on Sep 27, 2026
    1b29b4d
  5. lukemaj commented on Sep 27, 2026

    @lukemaj
    ContributorAuthor

    Handoff update: PR #136 head is now 1b29b4dcca3319776713732313966b8eb410f9f8 (single squashed commit, v12.5.0). Staleness now follows the upstream-sourced files (stale = bool(upstream_files)): local-only direction commits with unrelated upstream commits report ready with no warning. New test fails on af13cd7 and passes here. 302 tests OK, release-check OK, version-check CI green. Not merged; remaining gate: review/independent success on 1b29b4d, then human merge approval.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions