Skip to content

Refactor effective plan API and local vault sync - #9

Merged
lagrangee merged 2 commits into
mainfrom
codex/effective-plan-api
Sep 4, 2026
Merged

lagrangee merged 2 commits into
mainfrom
codex/effective-plan-api

Conversation

@lagrangee

Copy link
Copy Markdown
Owner

Problem

The Agent Plan read returned immutable revision packages, so repeated writes for the same dates produced redundant payloads and duplicate Obsidian week files. Plan readback also duplicated a Schedule request even though the effective dated Plan can prove the applied result.

Result

  • return schema-version-2 effective Plan reads with exactly one final Planned Day per date and deduplicated prescriptions
  • keep revision provenance on private authoring surfaces while removing it from the Agent read projection
  • verify single and batch Plan applications with one Plan readback
  • add /workout plan2local, stable natural-week vault files, effective source/manifest receipts, and vault README/Agent templates
  • migrate manifest-owned digest-named week shards only after verified replacement

Contract impact

GET /api/agent/v1/plan changes from revision-shaped schema version 1 to effective dated schema version 2. /schedule remains the explicit operational date-window resource with Session linkage. The local projection contract is added as training-plan-local-v1.

Verification

  • npm run check
  • npm run release-check
  • Workout skill quick validation (Skill is valid!)

Privacy, migration, and deployment

No credentials, private host paths, or personal training records are committed. The local vault remains a derived read-only projection. GitHub merge to main triggers the existing automatic Cloudflare deployment and operator acceptance workflow; no D1 migration is required.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-04T06:08:55.473342Z e9be04c PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e9be04c9ed

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/plan.js
Comment on lines +184 to +186
const lastDate = (state.planned_days ?? [])
.filter((/** @type {any} */ day) => day.date >= from)
.at(-1)?.date ?? from;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Bound the effective-plan date expansion

A Plan Update Package accepts any valid future effective_from, but this chooses that unrestricted last date as the end of the automatic Plan range. A mistaken or malicious update in a distant year therefore makes agentDatedPlan() call dateRange() across decades or millennia, producing an enormous response that can exceed Worker CPU/memory limits; because the far Planned Days remain materialized, subsequent Plan reads stay broken. Bound future plan dates or return a bounded/sparse projection.

Useful? React with 👍 / 👎.

const priorWeekPaths = Array.isArray(priorManifest?.week_paths) ? priorManifest.week_paths.filter(isManagedWeekPath) : [];
const staleWeekPaths = priorWeekPaths.filter((/** @type {string} */ path) => !currentWeekPaths.has(path));
const removedPaths = [];
for (const relativePath of [...staleWeekPaths, ...LEGACY_PLAN_PATHS]) if (await unlinkIfPresent(root, relativePath)) removedPaths.push(relativePath);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Require ownership evidence before deleting legacy paths

On every run, these legacy paths are deleted even when neither a prior manifest nor a legacy receipt establishes that plan2local created them. Thus a first run against an existing vault containing a human-authored plan/current.md or data/plan/current.json permanently removes that user data, despite the cleanup contract promising to preserve user-created notes. Only remove these paths when legacy ownership can be verified.

Useful? React with 👍 / 👎.

Comment on lines +227 to +229
for (const [relativePath, content] of weekFiles) await writeAtomicFile(join(root, relativePath), content, "utf8");
await writeAtomicFile(join(root, PLAN_SOURCE_PATH), sourceJson, "utf8");
await writeAtomicFile(join(root, PLAN_INDEX_PATH), indexMarkdown, "utf8");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Mark the generation pending before replacing files

When refreshing an existing successful projection, the managed week/source/index files are overwritten before the pending manifest is written. If any later write fails or the process is interrupted, some files may contain the new generation while the previous manifest still says write_status: complete and readback.status: verified, so later consumers can trust a mixed projection. Publish pending state before the first replacement or stage the full generation and switch it atomically.

Useful? React with 👍 / 👎.

@lagrangee
lagrangee merged commit 362bc2f into main Sep 4, 2026
1 of 2 checks passed
@lagrangee
lagrangee deleted the codex/effective-plan-api branch September 4, 2026 06: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