diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..c818acd --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,24 @@ +name: CI + +on: + pull_request: + branches: [main] + types: [ready_for_review] + push: + branches: [main] + +permissions: + contents: read + +jobs: + toolkit-tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + with: + persist-credentials: false + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 + with: + python-version: '3.11' + - run: ./run-tests.sh + - run: sha256sum --check MANIFEST.sha256 diff --git a/MANIFEST.sha256 b/MANIFEST.sha256 index 06e3379..44c8dec 100644 --- a/MANIFEST.sha256 +++ b/MANIFEST.sha256 @@ -18,14 +18,15 @@ a3414533de88c12d4fedfd5c1311c505dc87364674cc8e599a982cacbe1620c6 ./.agent/plan- 8c4e7fa9c1f9a84d5211c84c41cc20ed6a13a3ebc881bb175f1be6106db1fa85 ./.agent/plan-history/plan-summary.20260906T184718818166Z.101806a6188b911af737dd47187082418727ed7042831dd332d77360d1cb6b93.md a4d0bc13747cf250f25fb599b37f90cf519c95a29382f4da544afe9ff8095372 ./.agent/plan-history/plan-summary.20260907T162300226611Z.ddc507f2e3b9b24182cb6abc4eb4782feae98a0c25f8cdc174a2bf8c2c9932a1.md d60f352d0db1404c70afb4bb8b2ca3fd1c610572aa40720e8a0b7baa7885418c ./.gitattributes +13d683d7a117f01846724725f15a844768d16f52d226ec6d3f76143b1fc3f6f8 ./.github/workflows/ci.yml 15cefba6945d22a52b5b8ef6dd656fffcb698627b9fb23dacc5c8ec27ad1680d ./.gitignore 6d7a25701ba2532525fe556f1a55529ab09af6675522f749afb22609f7f8183e ./CODEX-INSTALL-PROMPT.md 6612129aca01053f15098204fb4bbaafdf85a667956202530bdcbc339e58e462 ./LICENSE e4912f4f8d644555dcd57d5e336a249cf8a9d7f6222b78096d6b403f45a8a215 ./PLAYGROUND.md -6eddb87e6d3e1e06141bbe43a88d112d9e1d017e6a365e7bba11e0da08988830 ./README.md +964bddcb73a1cd9492eaf0340987a5f33aa57cad53f4ca62e4c73e984f82fa3f ./README.md 979191eeef7975567b4c44c9fb6dc38bf78e431eda582ff55d4f37eb2f69a441 ./THIRD_PARTY.md 59b191889c8b7d098ddaf6b029f6f12b3ce6590893e1823f4448ad3b90c03fb4 ./assets/AGENTS.block.md -90edd43aadb411c3e0fbd99593785c20339c8f1c9a52ae8b4b87a96f073875c4 ./assets/hooks/session_start.py +b9f9eb58967f54b19fb3a58b1db32e4c25299ae10c06e2e45a6611c250801a71 ./assets/hooks/session_start.py 3027ffa3ef382dcd0c96f6280ba861bb4a9410011e1176d71d7aa7911805821f ./assets/runtime/repowise_bootstrap.py a564a3b00a86f43d38318b76168593bc965b2f1decf67a328d499a054aa35f36 ./assets/skills/adversarial-review/SKILL.md 78443f93e9ee4861a0d7a110af7e6d5f1e7d736e1459324530eb584c6b08ba58 ./assets/skills/adversarial-review/references/finding-format.md @@ -51,7 +52,7 @@ ac9ff3e77bb4958f6c7514c6ce7c4ca27e3638534bc8cd19753ea0f39f83e42e ./assets/skill 4acee4d97f68fc7b0d84e7fbe6f35d1e87b7a7f68c8bf624c2dcf79887623635 ./assets/skills/design-preflight/references/scope-boundaries.md cbe50a5f10a5adcf1725a7eddf56380ef8ac292e6fe32edfe069c5c02fdcc816 ./assets/skills/design-preflight/references/supported-model.md daafd85498937e8dd2914156fef193ea75e418d1ff49367e645d3c5bfcbe3b48 ./assets/skills/docs-maintainer/SKILL.md -a9b148f2415583aaee2c8cd17822138e8ff8770670534b55a2e6ff2e4f1a936c ./assets/skills/plan-history/SKILL.md +8d9900474c986b5a9c18fda2a2444e65ecd20ada61edce9779a1018ea08ccf6a ./assets/skills/plan-history/SKILL.md c67909e4aadda369b9550c09c5cc0311e3d86ef24f1965133eaf5cbdcbd84169 ./assets/skills/plan-history/agents/openai.yaml 5ac5175efb1ee5fcd32b14d120361d148c0c2983095dc4d0dc90fa6e8a27b756 ./assets/skills/publication/SKILL.md a9bf1bbaa51743d53b8646c34c2f277660213fe9fbf3aeb2ede30c077667be1c ./assets/skills/publication/references/publication.md @@ -121,12 +122,14 @@ d8f7dfc833661cbd58913b85d334adb88e3ea9f1f337925a351fa113b814311f ./docs/plans/c a2a2977403154705fc3d73fde0f45548c4722cc20b11cc189fe44f7982899224 ./docs/plans/cpk-055-native-ponytail.md 8df1adc8b9063bc5035e6b91a95f39e3dd571be8db66cc4ab5161f7f16e4c879 ./docs/plans/cpk-056-interviews-and-assessment.md a5d8013da3d22afba28c1259e29e3255d1d19969d0934b2f59069f0de80ea31b ./docs/plans/cpk-057-review-and-astra-guidance.md -2fd92d860f05222ec7543cf8aff83ff9424acc51c7ca2c617a039b6e3f1156cf ./docs/roadmap.md +5f2abf3bc85fbfc580d05139165ff95f29a3a85246bab2724c5f949eb93f26a5 ./docs/plans/cpk-058-plan-history-compaction.md +43141b61bf800dc9956603b6e88cdd0c3a5564340d3f4aee3fb6b0682dceee00 ./docs/plans/cpk-059-public-pr-release.md +c14438f22cad4a83b4409a72e75b589d19440d20516511bd7d4a419b27deb7ed ./docs/roadmap.md 6f8f14ca5fd8ad935eee66256b3f7c49d5c40957eedff938ba21365e30869719 ./doctor.ps1 ab56a88d9188979f06ea142d1f58ea0d6ad9088e83a965bd324209d83da513ad ./doctor.sh 8087bdb3ee654c0baac278a8e3bf85e33e314f8acfd486e7ebf675126a697058 ./install.ps1 3466d2e34145cfdaa83d793960794b2aefc96f3d9c48d22fd2af930ec819e9c4 ./install.sh -bc43e00be4e0adbb58a444f329cc9f6327b5d4ec2a00259f82bbc9e4820f7f77 ./kit.py +7843fa0b49e088495e603e8eb3ae6811cb40007d7b40bf3e621f7855d1722159 ./kit.py 331f17ca1486b5779d9b57a3a73834328eb3089ce612e636e6a8e5085899d61e ./run-tests.ps1 e6df9f1da02280a66161583529b06a34f0103041e9587afad0fac6074eecc15b ./run-tests.sh 85a2ba72e2b0cd1ab6c25a51f39059502415c3ac62a6bffa613d7e31b6422cd4 ./setup-repo.ps1 @@ -137,7 +140,7 @@ e1e231aac51822f7e1bb3aa61aba138cf8c5df9cefd3079b0c1b5a98eea03bd9 ./tests/fixtur a269775204ae7cad2457d00f5565c90da2df41a9719479f3489ec01afdd2519c ./tests/fixtures/cpk056-agent-cases.json e32941eb74be1f2cdcb6c82cf71e113b841651bf0d01786f364176de2da1b9c5 ./tests/fixtures/cpk056-agent-grading.json 289367b7090a0d71936b41f08c4a354bc2758013dceb709819de36a1b73d9aa6 ./tests/live_plan_history.py -a752cb4eb2a58614ab988106a83e9263bba3f30da9fb0f55bcd1a17375fcd1b9 ./tests/test_kit.py +74d96d387c814f60e37f0ba682bb42e1ba05b729c866b929d026166a4a9be4c9 ./tests/test_kit.py cfa479b5248a628ecd71194b7ac4a36bcddf17af7eb52ca2a6c3cd0566269927 ./tests/test_ponytail.py d16f7eadc8c668e82a1d0d2554ed04def15cb0a4b2ce13ac1ce1339bc0e62161 ./uninstall.ps1 f12cff94ef7f9b0ca489cbe43e1de737011476966e04c1578f4977177b0da217 ./uninstall.sh diff --git a/README.md b/README.md index aca8824..c1e4434 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,8 @@ The edit hooks update `/.codex/roadmap-view.md` after an agent The [Plan history skill](assets/skills/plan-history/SKILL.md) keeps repository summaries versioned in `.agent/plan-history/`. Specification associations stay in each record. Later planning sessions find these records across worktrees and reconcile their decisions. +For large histories, agents create reusable reading summaries under `.agent/plan-history/compacted/`. Original records remain unchanged. The skill also preserves reading progress across normal context compaction. + An unrecorded destination skill is a conflict. The installer stops before it changes that directory. Open a new Codex session after installation. Use `/hooks` to review and trust the toolkit and Ponytail commands. @@ -264,6 +266,12 @@ Repository-owned `AGENTS.md`, `.agent/PLANS.md`, roadmaps, and other project doc Remove the toolkit source checkout or downloaded archive only when you no longer need it. Leave unrelated Codex configuration and other plugins intact. +## Contributing + +Changes use draft pull requests and Codex review before readiness. The required `toolkit-tests` check runs when a PR becomes ready and after pushes to `main`. It runs the toolkit tests and verifies distribution checksums. + +Protected `main` requires a pull request, passing CI, and resolved conversations. Codex review is a separate publication gate; no additional human approval is required. Follow the [publication procedure](assets/skills/publication/references/publication.md). + ## Verification On macOS or Linux, run: diff --git a/assets/hooks/session_start.py b/assets/hooks/session_start.py index 62a64ec..3fd7416 100755 --- a/assets/hooks/session_start.py +++ b/assets/hooks/session_start.py @@ -390,7 +390,7 @@ def save_transcript_plan(event: dict[str, object]) -> list[str]: warnings = save_transcript_plan(event) context = "Codex Practical Kit is active. Read the managed AGENTS.md links that apply to this task." if event.get("source") == "compact": - context += " Apply repository-knowledge before the next repository lookup. Keep it active until the task ends. Before later planning, use plan-history and reconcile all applicable records." + context += " Apply repository-knowledge before the next repository lookup. Keep it active until the task ends. Use plan-history to resume saved reconciliation after compaction." if warnings: context += " Plan history warning: " + "; ".join(warnings) print(json.dumps({ diff --git a/assets/skills/plan-history/SKILL.md b/assets/skills/plan-history/SKILL.md index d8cfc61..fc60c9f 100644 --- a/assets/skills/plan-history/SKILL.md +++ b/assets/skills/plan-history/SKILL.md @@ -8,7 +8,8 @@ description: > --- - + + @@ -31,17 +32,62 @@ Specification markers in the saved response retain its associations. Do not crea Apply [Repository knowledge](../repository-knowledge/SKILL.md) first. Use RepoWise to identify the repository, task, ExecPlan, and related specifications. -Read every applicable Plan history record before later planning. +Account for every applicable Plan history record before later planning. Read original records or reuse verified summaries through the procedure below. -Then enumerate files directly. In a Git repository, use `git worktree list --porcelain -z` to find every worktree. Read every file in `.agent/plan-history/` in each worktree. For each identified specification, also read legacy siblings named `.plan-summary.*.md` in those worktrees. Also inspect the current global fallback directory when the prompt identifies a prior storage warning. +Then enumerate files directly. In a Git repository, use `git worktree list --porcelain -z` to find every worktree. Inventory every original record in `.agent/plan-history/` in each worktree. Enumerate `compacted/*.md` separately; these derived summaries are not original captures. For each identified specification, also read legacy siblings named `.plan-summary.*.md` in those worktrees. Also inspect the current global fallback directory when the prompt identifies a prior storage warning. Use the same discovery before implementation when the user resumes or implements a plan after context was cleared. Resume from the ExecPlan specification, applicable Plan history, roadmap state, the Git worktree and completed checkpoint history, the ignored task result when it exists, and the current conversation when available. Do not infer operational status from the ExecPlan. -Do not trust a RepoWise match limit or index freshness as proof that no record exists. Do not select the first match. Deduplicate only records with the same event key and identical bytes. Retain and reconcile every distinct-content collision record. Read each unique record completely. +Do not trust a RepoWise match limit or index freshness as proof that no record exists. Do not select the first match. Deduplicate only records with the same event key and identical bytes. Retain and reconcile every distinct-content collision record. Record each original's path, event key, filename timestamp, and SHA-256 of its complete bytes. Keep path aliases for identical copies across worktrees. -If the complete applicable set cannot fit in context, stop. List every unread path. Do not continue with partial history. +Context size and ordinary context compaction never require a history-reading stop. Process history in bounded reads, including chunks within one large record. Complete reconciliation before planning continues; the raw history need not fit in one context window. + +## Reusable summaries + +Keep derived summaries in `.agent/plan-history/compacted/..md`, versioned with the task. Outside Git, use `compacted/` under the existing global fallback directory. Never overwrite a summary revision. Create a new file when its content changes. Keep original captures unchanged and retain their last copies. + +A summary is a reading aid, not a new specification, accepted decision, or task-status record. Its scope identifies the topics and specification associations it covers. A new task can reuse it within that scope. A broader task must reopen the original evidence for the added scope. + +Each summary contains: + +- `Scope`: covered topics, specification associations, and explicit exclusions. +- `Sources`: original paths, event keys, filename timestamps, complete-byte SHA-256 hashes, and source anchors for the decisions. +- `Decisions`: requirements, constraints, acceptance criteria, rejected options, and reasons within that scope, attributed to their originals. +- `Supersessions`: the original record, reason, replacement, and exact scope; retain carried decisions outside that scope. +- `Conflicts`: unresolved questions and conflicting decisions, with both original sources. Use an explicit `none` when absent. +- `Verification`: which complete originals were read and compared with the summary, including their hashes. Include the paths and hashes of any separate supersession evidence. + +Read each uncovered original completely before certifying its summary coverage. Compare the draft against each original while that source is available. Preserve every decision within the declared scope. A SHA-256 match proves byte identity, not semantic fidelity. Do not certify a summary from a filename, partial read, or another summary alone. + +Keep summaries small enough to read in batches. Split them by source or topic when needed, retaining direct original references in every part. Do not build chains of summaries of summaries. Read a large summary in chunks and retain its relevant decisions outside conversation context. + +Before reuse, compare the current inventory with each summary's source identities and hashes. Check its scope and verification record. Read and reconcile new, uncovered, changed, or distinct-content records. A summary cannot prove that no newer record exists. + +If summary evidence is missing, stale, incomplete, or inconsistent, reread the affected originals and create corrected derived evidence. Reuse unaffected verified summaries. If summaries disagree, inspect their originals before treating the disagreement as a decision conflict. Original evidence takes precedence. + +Use original filename timestamps for reconciliation, not summary creation times. Apply the conflict and supersession rules below across all batches and summaries. A newer summary cannot authorize a replacement decision. + +## Bounded reads and resumption + +Keep reading progress in the existing ignored `.agent/test-results/.md` working record, outside the reusable summaries. Outside Git, use an untracked working file beside the fallback history. Save a checkpoint before long reads and after each completed chunk or batch. Include: + +- The task scope and complete source inventory, including identities, hashes, and any aliases. +- Reused summary paths and hashes, with their verified coverage. +- Completed records, pending records, and the next source range to read. +- For a partial record: its complete-byte hash, consumed ranges, and provisional decisions. Do not mark that record complete. +- Retained decisions, source anchors, unresolved conflicts, and supersession evidence needed to reconcile later batches. + +After ordinary context compaction, resume this checkpoint through Plan History. Validate the saved source and summary hashes, then continue from the first unaccounted range. A context reset does not invalidate verified coverage. Do not restart all raw reads merely because their text left the context window. + +If the checkpoint is absent or incomplete, reconstruct coverage from verified reusable summaries. Reread only evidence whose coverage or retained decisions cannot be established. If a partially read source changed, reread that source from its beginning. Preserve unaffected coverage. + +Partition a large reconciliation by topic or decision owner. Keep cross-topic references and outstanding comparisons in the working record. Do not discard unresolved decisions to meet a context budget. + +Before declaring reconciliation complete, enumerate the original inventory again and account for every addition or change. Every applicable original must have complete direct-read coverage or verified summary coverage for this task's scope. Empty history needs no summary. Continue reading while coverage is incomplete; do not emit a plan based on an unread tail. + +An actually unreadable required source or an unresolved source-backed decision conflict remains a blocker. Report the exact source and reason. Context compaction alone is neither failure nor evidence of a conflict. ## Reconcile decisions @@ -60,7 +106,7 @@ Stop planning when retained decisions conflict without a recorded supersession. ## Replan checkpointed work -Before a replan, read the current ExecPlan, every applicable Plan record, and the completed checkpoint history in Git. +Before a replan, read the current ExecPlan and completed checkpoint history in Git. Account for every applicable Plan record through the reading and summary procedure above. Keep accepted contracts unchanged. Use completed checkpoint history in Git as immutable operational evidence. Split, merge, reorder, or replace only unfinished subtasks. Never amend or rewrite a completed checkpoint commit. @@ -88,7 +134,7 @@ Do not omit the marker. Do not use an absolute path or a path outside the reposi ## Implementation handoff -Link every applicable record from the task ExecPlan. Treat each linked decision as an implementation constraint. +Link every applicable original record from the task ExecPlan. Summary links are supplemental; they do not replace original links. Treat each linked decision as an implementation constraint. Relocate applicable untracked Plan records to the task worktree before task edits. diff --git a/docs/plans/cpk-058-plan-history-compaction.md b/docs/plans/cpk-058-plan-history-compaction.md new file mode 100644 index 0000000..9e5b1c3 --- /dev/null +++ b/docs/plans/cpk-058-plan-history-compaction.md @@ -0,0 +1,120 @@ +# Compact Plan History without losing source evidence + + +This ExecPlan follows [PLANS.md](../../.agent/PLANS.md). It defines the CPK-058 reading-method change. + +## Purpose + + +Large Plan histories must remain usable across context windows and future tasks. An agent reads bounded batches, retains decisions outside conversation context, and reuses verified summaries. It never deletes original Plan captures to reduce context use. + +The user requested this method on 2026-09-15 and selected reusable summaries with links to unchanged originals. Normal context compaction during a read must resume the work instead of triggering the old size-only stop. + +## Context and isolation + + +Use branch `task/cpk-058-plan-history-compaction` from synchronized `main` at `6cc881661646e2bb0c96e07fcf56897e7f7cbf5f`. There is one writable stream. + +`assets/skills/plan-history/SKILL.md` owns history discovery, reading, and reconciliation. Its old instruction stops when the complete applicable history cannot fit in context. `assets/hooks/session_start.py` routes compact-session starts back to this skill. That hook has no context-capacity detector or reading checkpoint. + +`tests/test_kit.py` checks the installed instructions and executes the real hook for startup and compact events. `README.md` describes the user-visible storage behavior. Original captures remain in `.agent/plan-history/` and travel through Git. + +A derived summary is a scoped reading aid. Its source inventory identifies the complete original bytes that it summarizes. It neither replaces those originals nor becomes another implementation plan. + +## Decision Log + + +- Decision: Extend the existing instruction owner with reusable Markdown summaries and bounded reading checkpoints. + Rationale: The failure is an instruction-level stop. A new summarization service, parser, database, or token-limit setting is unnecessary. +- Decision: Store derived evidence in `.agent/plan-history/compacted/`, separately from original captures. Keep mutable reading progress in the ignored task result. + Rationale: Future tasks can reuse evidence through Git without confusing it with captured Plan responses or tracked lifecycle status. +- Decision: Require original source hashes, scope, decision anchors, and explicit fidelity verification before reuse. + Rationale: A hash detects changed bytes but cannot prove that a summary preserved their meaning. A broader task must reopen uncovered scope. +- Decision: Preserve original timestamps, conflict evidence, scoped supersession, and decisions outside a replacement's scope. + Rationale: A newer summary must not silently override an older accepted decision. +- Decision: Split large sources and summaries into bounded reads and save progress after chunks. + Rationale: The method must work when even one original exceeds the comfortable reading budget. Missing checkpoints require evidence reconstruction, not a context-size stop. +- Decision: Use direct original references instead of recursive summary chains. + Rationale: Each summary can be checked and replaced independently when its evidence changes. +- Decision: Validate the procedure as instructions and validate routing through the existing hook subprocess test. + Rationale: No executable semantic compressor is added. These checks cannot establish a general model-fidelity rate or reproduce the user's suspected app interruption. + +## Product boundary and reconciliation + + +Apply [Scope boundaries](../../assets/skills/design-preflight/references/scope-boundaries.md) and [Supported model](../../assets/skills/design-preflight/references/supported-model.md). Normal use includes one writer, local files, Git worktrees, new history records, future tasks, and ordinary context compaction during reads. + +The Plan History reading procedure, derived-summary format, compact routing text, and related checks are `composes`. Original capture timing, marker parsing, event identity, byte-preserving storage, repository setup, publication, and original-record relocation remain `opaque`. No filesystem-fault recovery, concurrent writer coordination, automatic compaction API, model selection, or external-project change is included. + +The user's current request replaces the literal all-originals-in-context requirement and size-only stop. Preserve complete evidence coverage and genuine source-backed conflict stops. This supersedes only those reading restrictions in the current Plan History owner and the unchanged-reconciliation boundary of [CPK-054](cpk-054-internal-plan-history.md). The exact-capture and source-authority contract of [CPK-036](cpk-036-plan-history.md) remains. + +Carry the prior records and their recorded scoped supersessions. CPK-054 remains authoritative for central-only capture and one-way byte-verified handoff. CPK-044 and final CPK-046 remain authoritative for native review. CPK-053 excludes static instruction changes from production trace closure. CPK-055 preserves upstream Ponytail ownership. CPK-056 and CPK-057 retain bounded correction, validation, and communication rules. Their prior assessment work is not repeated here. + +Applicable original records (retain their recorded supersessions): + +- [Original 1](../../.agent/plan-history/plan-summary.20260819T195712262086Z.manual-recovery.md) +- [Original 2](../../.agent/plan-history/plan-summary.20260819T211423672232Z.manual-recovery.md) +- [Original 3](../../.agent/plan-history/plan-summary.20260822T050100617085Z.fd7dfe4c94e461a1824112794d31e1372d316ccf79eed8a3937d2754c1157e40.md) +- [Original 4](../../.agent/plan-history/plan-summary.20260822T065923051937Z.4415ee79c8b0327ba824768113192b4f60662d355fb4931876ec995a214a5526.md) +- [Original 5](../../.agent/plan-history/plan-summary.20260823T052048899607Z.c539b46a7e5fa56092a382fef046fd00d4271c42c4fda8e0f0e2216ce94df122.md) +- [Original 6](../../.agent/plan-history/plan-summary.20260824T031427928859Z.f30d03e6b396d05f07f5ce7eebc8b8e8b81e2b1cfe8ebc739342a6e444ca6968.md) +- [Original 7](../../.agent/plan-history/plan-summary.20260824T135017227348Z.7cfbec79d5ce39f1a1d436a31dccfe0669c616f252b6793d4b90dc2b34ad13d6.md) +- [Original 8](../../.agent/plan-history/plan-summary.20260824T164719361941Z.f1479c9effab9071b8ccaa86dce1dbee407b79647c6bb7d542aea8c75caae32b.md) +- [Original 9](../../.agent/plan-history/plan-summary.20260825T002758364682Z.4eba52594f2ef5bdbe93f4f0ead7b61802e894668d23c749b5af459f65a19437.md) +- [Original 10](../../.agent/plan-history/plan-summary.20260825T002911279202Z.940432714b78524077326cf1dea7571142fa6038e878a2fb7e884024bc8775a8.md) +- [Original 11](../../.agent/plan-history/plan-summary.20260825T172626414955Z.9eaf7888a286b18f69d5a94869ee99522214d23dd715a553664a2041108fced3.md) +- [Original 12](../../.agent/plan-history/plan-summary.20260825T173129857080Z.a3ee26a1802fb85c5a0a100ccb3c33c1a6fff358bd20b65636adc61f8d0de377.md) +- [Original 13](../../.agent/plan-history/plan-summary.20260825T183857932150Z.47ec1ac118b8c6c23f961b4099708aacc7031581a744bc389e6795e1c2007796.md) +- [Original 14](../../.agent/plan-history/plan-summary.20260901T024803899174Z.f5becdd56d889aba50bf375a29ab0feb9012128e404e73e7a664e0243eb5ab8f.md) +- [Original 15](../../.agent/plan-history/plan-summary.20260906T145108959420Z.4ca59f1efb35d2fec6091bc88b5848bb2e50226576f0a493f9ec85ed1838c57b.md) +- [Original 16](../../.agent/plan-history/plan-summary.20260906T161604059175Z.811836c214ecc89cb39c692f4366e4e79e56a698bf0d01445feb86fcd2c725f4.md) +- [Original 17](../../.agent/plan-history/plan-summary.20260906T184718818166Z.101806a6188b911af737dd47187082418727ed7042831dd332d77360d1cb6b93.md) +- [Original 18](../../.agent/plan-history/plan-summary.20260907T162300226611Z.ddc507f2e3b9b24182cb6abc4eb4782feae98a0c25f8cdc174a2bf8c2c9932a1.md) + +## Boundary inventory and checks + + +| Boundary | Required distinction | Check | +| --- | --- | --- | +| B1 | Small versus oversized history, including a decisive clause beyond the first chunk of one original | Existing history contract test requires intra-record chunks, complete coverage, and no unread-tail planning | +| B2 | Uninterrupted versus compacted reading, including a partial record and a missing checkpoint | Existing hook subprocess test checks compact routing; history contract checks saved ranges, hash validation, and reconstruction | +| B3 | Valid future-task summary versus new, changed, incomplete, or out-of-scope evidence | History contract checks direct originals, scope, verification, stale-evidence rereading, and supplemental original links | +| B4 | Empty or singleton inventory versus duplicate prefix followed by a distinct record or collision | Preserve full discovery and event-plus-byte identity; check separate derived-summary discovery and final inventory enumeration | +| B5 | Explicit supersession versus unresolved cross-batch conflict; scoped replacement versus unaffected decisions | Preserve canonical supersession fields, original order, both conflict sources, and carried decisions outside scope | + +The fresh preflight challenger independently derives the source clauses and these distinctions, then checks the concrete procedure. These are instruction boundaries, not a new executable history subsystem. + +## Implementation + + +Use one atomic subtask, CP1, with one full native-review and local-commit boundary. Replace the size-only stop and raw-reread wording in the existing Plan History owner. Define the summary fields, reuse validation, bounded reads, resumable working checkpoint, final inventory check, and actual blocking conditions there. + +Change only the compact-session reminder in `assets/hooks/session_start.py` to route to saved reconciliation. Preserve the event dispatch, capture behavior, and output format. Extend the existing history contract and startup/compact tests in `tests/test_kit.py`. Add a short user-facing description beside the current Plan History paragraph in `README.md`. + +Do not add a compression helper or create speculative summaries for unrelated topics. Agents create scoped derived summaries when history size or subsequent reuse needs them. Summary revisions are immutable; verification errors produce new derived evidence while preserving originals. + +## Validation and acceptance + + +From the repository root, run: + + python3 -m unittest discover -s tests -p test_kit.py -k plan_history_is_immutable + python3 -m unittest discover -s tests -p test_kit.py -k session_start_still + ./run-tests.sh + git diff --check + sha256sum --check MANIFEST.sha256 + +Regenerate affected manifest hashes before the checksum check. Run applicable shell and PowerShell syntax checks. Keep full commands, results, source-read inventory, and native review output in `.agent/test-results/cpk-058-plan-history-compaction.md`. + +Walk through five concrete examples against the procedure: a large record with a trailing constraint; compaction after a partial read; a valid reused summary followed by a new record; a duplicate prefix followed by a different-content collision; and a cross-summary conflict with and without a scoped supersession. In each case identify the retained evidence, next read, and whether planning can continue. These examples assess the procedure's completeness, not observed model reliability. + +After clean native review, close the roadmap entry and create the local commit. Install the candidate with `./install.sh`; require `./doctor.sh` to report `Result: ready`. Publication and version selection remain separate. + +## Recovery and dependencies + + +Use existing Git and ordinary Markdown files. Use SHA-256 tools to identify complete source bytes. A missing or stale derived summary permits rereading its original evidence. A changed partial source restarts that source, preserving unaffected coverage. A genuinely unreadable required original or unresolved original-source conflict remains a specific blocker. + +No automatic context reset is required. A completed checkpoint remains usable after one occurs. The agent can partition large reconciliation by topic while retaining cross-topic references in its working record. + +Revision: add reusable derived evidence and resumable reads in response to the user's history-capacity and compaction report. diff --git a/docs/plans/cpk-059-public-pr-release.md b/docs/plans/cpk-059-public-pr-release.md new file mode 100644 index 0000000..9287525 --- /dev/null +++ b/docs/plans/cpk-059-public-pr-release.md @@ -0,0 +1,104 @@ +# Publish Plan History through protected pull requests + + +This ExecPlan follows [PLANS.md](../../.agent/PLANS.md) and defines CPK-059. + +## Purpose + + +Release reusable Plan History as version `0.24.0` from a public repository. Changes enter `main` through reviewed pull requests and required CI. A pull request remains draft during Codex review, then readiness starts the required checks. + +## Context and boundary + + +Use `task/cpk-059-public-pr-release` from `3ced26461e9de5e97082d0b7c9e0ce1c0f4fd453`. The repository is `calculatetech/codex-practical-kit`. Its initial main commit is `6cc881661646e2bb0c96e07fcf56897e7f7cbf5f`. + +The user requested public visibility, branch protection, publication, and release. The user selected Codex review plus required CI without an additional human approval. + +Apply [Scope boundaries](../../assets/skills/design-preflight/references/scope-boundaries.md) and [Supported model](../../assets/skills/design-preflight/references/supported-model.md). Workflow configuration, native GitHub settings, version identity, and release delivery are composed here. The existing test launcher, installer, and [CPK-058 implementation](cpk-058-plan-history-compaction.md) remain unchanged owners. + +Normal use is a single writer with GitHub administrator access and a configured Codex GitHub review connection. Preserve unrelated untracked files. No new review service, credentials, platform matrix, cleanup, or production runtime is needed. + +## Decision Log + + +- Decision: Release `0.24.0` under the [version policy](../../assets/skills/publication/references/versioning.md). + Rationale: CPK-058 adds reusable summaries and resumable reads, a new capability beyond `0.23.9`. +- Decision: Use one native GitHub Actions job, `toolkit-tests`. + Rationale: The existing standard-library suite and checksum command provide the needed checks without a new dependency. +- Decision: Trigger only on PR `ready_for_review` targeting `main`, and pushes to `main`. + Rationale: Task pushes and draft creation must not spend hosted CI. Explicit event types exclude the default PR events. +- Decision: Require zero formal approving reviews while retaining a clean Codex review as a publication gate. + Rationale: The repository has one owner. A Codex thumbs-up is evidence for the publication procedure, not a formal GitHub approval. +- Decision: Use native branch protection and squash merges. + Rationale: GitHub already provides required checks, conversations, administrator enforcement, and linear history. + +## Implementation + + +Use one atomic subtask, CP1, with one full native-review and local-commit boundary. Its primary owner is `.github/workflows/ci.yml`; settings and release consume that workflow. + +Create the workflow named `CI`. Its only events are `pull_request` with `branches: [main]` and `types: [ready_for_review]`, plus `push` with `branches: [main]`. Grant only `contents: read`. + +Define `toolkit-tests` on `ubuntu-latest`. Use `actions/checkout@11d5960a326750d5838078e36cf38b85af677262` with `persist-credentials: false`. Use `actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065` with Python `3.11`. Run `./run-tests.sh`, then `sha256sum --check MANIFEST.sha256`. Do not skip steps or tolerate failures. + +Set `kit.py`'s `KIT_VERSION` and its existing test assertion to `0.24.0`. Add one static workflow test in `tests/test_kit.py`. It enumerates all workflow files and rejects extra triggers or conditional check suppression. Update README contribution instructions and distribution checksums. + +After local review, set repository visibility to public and allow only squash merging. Configure main protection with strict required status context `toolkit-tests`, administrator enforcement, resolved conversations, and linear history. Disable force pushes and deletion. Set required approving count to zero, dismiss stale reviews, and require neither code-owner nor last-push human approval. Keep push restrictions null. Read back the actual settings. + +Use the [publication procedure](../../assets/skills/publication/references/publication.md) for local closure, installation, draft review, readiness, squash merge, and integration. The first PR supplies the missing workflow through its merge ref. Prove the complete workflow inventory before the task push. Verify the actual hosted Codex response before readiness. + +After integration and passing main CI, create the unused tag and full GitHub release `v0.24.0` at the exact integrated main commit. Release notes describe reusable summaries, resumable reading, and the PR workflow. Link the versioned README and the full changelog since the previous release, `v0.23.2`. + +## Validation and acceptance + + +Run from the repository root: + + ./run-tests.sh + sh -n doctor.sh install.sh run-tests.sh setup-repo.sh uninstall.sh + git diff --check + sha256sum --check MANIFEST.sha256 + +Require the suite to pass and every checksum to match. Validate workflow structure with an available YAML parser without adding a package dependency. After review, install with `./install.sh` and require `./doctor.sh` to report `Result: ready` for `0.24.0`. + +| Boundary | Observable evidence | +| --- | --- | +| B1: protection | API readback shows public visibility, PRs, strict required CI, conversations, administrator enforcement, and zero extra approvals | +| B2: CI timing | Complete workflow inventory excludes task pushes and draft events; actual readiness starts `toolkit-tests` | +| B3: review identity | Frozen local commit equals remote branch and PR head; clean hosted review applies to that head | +| B4: merge gates | All paginated checks and conversations are accounted for; checks pass, no changes are requested, and GitHub reports mergeability | +| B5: integration | Clean local main fast-forwards to origin/main, contains the squash result, and passes main CI | +| B6: release identity | Source version and checksums agree; unused `v0.24.0` resolves to integrated main; release is neither draft nor prerelease | +| B7: consumption | Reviewed-candidate installation and Doctor succeed | + +If a correction occurs, repeat the current-head gates through the canonical procedure. Do not manufacture a correction to test this path. Static configuration invokes the unchanged launcher; it adds no production path requiring semantic trace closure. + +## Plan history and recovery + + +Carry the original records and scoped supersessions reconciled in CPK-058. The reading checkpoint can be reused after complete source identity and hash verification. Publication and native-review contracts remain in force. The current request adds public repository setup and a release; it does not reopen the CPK-058 implementation. + +- [Original 1](../../.agent/plan-history/plan-summary.20260819T195712262086Z.manual-recovery.md) +- [Original 2](../../.agent/plan-history/plan-summary.20260819T211423672232Z.manual-recovery.md) +- [Original 3](../../.agent/plan-history/plan-summary.20260822T050100617085Z.fd7dfe4c94e461a1824112794d31e1372d316ccf79eed8a3937d2754c1157e40.md) +- [Original 4](../../.agent/plan-history/plan-summary.20260822T065923051937Z.4415ee79c8b0327ba824768113192b4f60662d355fb4931876ec995a214a5526.md) +- [Original 5](../../.agent/plan-history/plan-summary.20260823T052048899607Z.c539b46a7e5fa56092a382fef046fd00d4271c42c4fda8e0f0e2216ce94df122.md) +- [Original 6](../../.agent/plan-history/plan-summary.20260824T031427928859Z.f30d03e6b396d05f07f5ce7eebc8b8e8b81e2b1cfe8ebc739342a6e444ca6968.md) +- [Original 7](../../.agent/plan-history/plan-summary.20260824T135017227348Z.7cfbec79d5ce39f1a1d436a31dccfe0669c616f252b6793d4b90dc2b34ad13d6.md) +- [Original 8](../../.agent/plan-history/plan-summary.20260824T164719361941Z.f1479c9effab9071b8ccaa86dce1dbee407b79647c6bb7d542aea8c75caae32b.md) +- [Original 9](../../.agent/plan-history/plan-summary.20260825T002758364682Z.4eba52594f2ef5bdbe93f4f0ead7b61802e894668d23c749b5af459f65a19437.md) +- [Original 10](../../.agent/plan-history/plan-summary.20260825T002911279202Z.940432714b78524077326cf1dea7571142fa6038e878a2fb7e884024bc8775a8.md) +- [Original 11](../../.agent/plan-history/plan-summary.20260825T172626414955Z.9eaf7888a286b18f69d5a94869ee99522214d23dd715a553664a2041108fced3.md) +- [Original 12](../../.agent/plan-history/plan-summary.20260825T173129857080Z.a3ee26a1802fb85c5a0a100ccb3c33c1a6fff358bd20b65636adc61f8d0de377.md) +- [Original 13](../../.agent/plan-history/plan-summary.20260825T183857932150Z.47ec1ac118b8c6c23f961b4099708aacc7031581a744bc389e6795e1c2007796.md) +- [Original 14](../../.agent/plan-history/plan-summary.20260901T024803899174Z.f5becdd56d889aba50bf375a29ab0feb9012128e404e73e7a664e0243eb5ab8f.md) +- [Original 15](../../.agent/plan-history/plan-summary.20260906T145108959420Z.4ca59f1efb35d2fec6091bc88b5848bb2e50226576f0a493f9ec85ed1838c57b.md) +- [Original 16](../../.agent/plan-history/plan-summary.20260906T161604059175Z.811836c214ecc89cb39c692f4366e4e79e56a698bf0d01445feb86fcd2c725f4.md) +- [Original 17](../../.agent/plan-history/plan-summary.20260906T184718818166Z.101806a6188b911af737dd47187082418727ed7042831dd332d77360d1cb6b93.md) +- [Original 18](../../.agent/plan-history/plan-summary.20260907T162300226611Z.ddc507f2e3b9b24182cb6abc4eb4782feae98a0c25f8cdc174a2bf8c2c9932a1.md) + + +Record operational evidence in `.agent/test-results/cpk-059-public-pr-release.md`. Preserve existing remote state after an actual failure. Never move or recreate a published tag. A missing hosted review connection requires configuration before readiness. Do not bypass protected main or discard local changes. + +Revision: define native CI, protection, and versioned release in response to the user's publication request and selected solo review gate. diff --git a/docs/roadmap.md b/docs/roadmap.md index 43df91a..e9e3326 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -33,6 +33,8 @@ No residual risk is accepted. ## Completed +- ✅ **CPK-059 — Publish through protected pull requests.** Add readiness-triggered CI, make the repository public, protect main, and release reusable Plan History as version `0.24.0`. [ExecPlan](plans/cpk-059-public-pr-release.md) +- ✅ **CPK-058 — Compact Plan History and resume interrupted reads.** Reuse verified summaries without changing original records, and preserve reading progress across normal context compaction. [ExecPlan](plans/cpk-058-plan-history-compaction.md) - ✅ **CPK-057 — Separate review from testing and complete Astra guidance.** Keep test execution before review and add bounded autonomy, clear communication, and useful delegation to the existing rule owners. [ExecPlan](plans/cpk-057-review-and-astra-guidance.md) - ✅ **CPK-056 — Improve interviews and assess rule adherence.** Bound material questions by their prerequisites, clarify correction and proof rules, and compare agent behavior through independent assessment cases. [ExecPlan](plans/cpk-056-interviews-and-assessment.md) - ✅ **CPK-055 — Install the official Ponytail plugin.** Preserve upstream skills, hooks, modes, and user settings through native Codex installation. Remove toolkit mode overrides and document complete component removal. diff --git a/kit.py b/kit.py index 3db3923..5d71337 100755 --- a/kit.py +++ b/kit.py @@ -24,7 +24,7 @@ from typing import Any, Iterable KIT_ID = "codex-practical-kit" -KIT_VERSION = "0.23.9" +KIT_VERSION = "0.24.0" REPOWISE_VERSION = "0.45.0" UV_VERSION = "0.12.4" UV_INSTALLER_URL = f"https://astral.sh/uv/{UV_VERSION}/install.sh" diff --git a/tests/test_kit.py b/tests/test_kit.py index 17e4051..0e137de 100644 --- a/tests/test_kit.py +++ b/tests/test_kit.py @@ -345,6 +345,7 @@ def test_session_start_still_announces_router(self): self.assertIn("repository-knowledge", contexts["compact"]) self.assertIn("until the task ends", contexts["compact"]) self.assertIn("plan-history", contexts["compact"]) + self.assertIn("resume saved reconciliation after compaction", contexts["compact"]) def test_copy_reinstall_and_uninstall(self): with tempfile.TemporaryDirectory() as temp: @@ -3426,7 +3427,8 @@ def test_execplans_split_semantically_and_replans_preserve_checkpoints(self): self.assertIn(required_fact, plans) self.assertIn("one final review of the complete task", plans) - self.assertIn("current ExecPlan, every applicable Plan record", history) + self.assertIn("Before a replan, read the current ExecPlan", history) + self.assertIn("Account for every applicable Plan record through the reading and summary procedure", history) self.assertIn("completed checkpoint history in Git", history) self.assertIn("Split, merge, reorder, or replace only unfinished subtasks", history) self.assertIn("Never amend or rewrite a completed checkpoint commit", history) @@ -3453,10 +3455,33 @@ def test_lifecycle_skills_and_version(self): self.assertIn("`pwsh -File .\\doctor.ps1`", publication) self.assertIn("from the reviewed candidate", publication) self.assertIn("`Result: ready`", publication) - self.assertEqual(kit.KIT_VERSION, "0.23.9") + self.assertEqual(kit.KIT_VERSION, "0.24.0") self.assertNotIn("Version `0.22.0`", (ROOT / "README.md").read_text()) self.assertNotIn("version 0.22.0", (ROOT / "CODEX-INSTALL-PROMPT.md").read_text()) + def test_ci_runs_only_after_readiness_or_main_push(self): + directory = ROOT / ".github" / "workflows" + self.assertEqual({p.name for p in directory.iterdir()}, {"ci.yml"}) + workflow = (directory / "ci.yml").read_text() + self.assertEqual(workflow.split("jobs:", 1)[0], """name: CI + +on: + pull_request: + branches: [main] + types: [ready_for_review] + push: + branches: [main] + +permissions: + contents: read + +""") + self.assertIn(" toolkit-tests:\n", workflow) + self.assertIn(" - run: ./run-tests.sh\n", workflow) + self.assertIn(" - run: sha256sum --check MANIFEST.sha256\n", workflow) + self.assertNotIn("continue-on-error:", workflow) + self.assertNotIn("if:", workflow) + def test_pr_publication_reviews_draft_before_ci(self): root = ROOT / "assets" / "skills" publication = (root / "publication" / "references" / "publication.md").read_text() @@ -3558,11 +3583,31 @@ def test_plan_history_is_immutable_and_complete(self): self.assertIn("plan-history", kit.CUSTOM_SKILLS) self.assertIn("cpk-rule-owner: plan-history", skill) - self.assertIn("Read every file in `.agent/plan-history/`", skill) + self.assertIn("Inventory every original record in `.agent/plan-history/`", skill) self.assertIn("before the next submitted prompt continues", skill) self.assertIn("Every repository Plan capture has a record", skill) self.assertIn("Do not trust a RepoWise match limit", skill) - self.assertIn("Do not continue with partial history", skill) + self.assertNotIn("If the complete applicable set cannot fit in context, stop", skill) + self.assertIn("including chunks within one large record", skill) + self.assertIn("Every applicable original must have complete direct-read coverage or verified summary coverage", skill) + self.assertIn("enumerate the original inventory again", skill) + self.assertIn("do not emit a plan based on an unread tail", skill) + self.assertIn("compacted/..md", skill) + self.assertIn("these derived summaries are not original captures", skill) + self.assertIn("A broader task must reopen the original evidence", skill) + self.assertIn("A SHA-256 match proves byte identity, not semantic fidelity", skill) + self.assertIn("Do not build chains of summaries of summaries", skill) + self.assertIn("new, uncovered, changed, or distinct-content records", skill) + self.assertIn("Original evidence takes precedence", skill) + self.assertIn("retain carried decisions outside that scope", skill) + self.assertIn("both original sources", skill) + self.assertIn("not summary creation times", skill) + self.assertIn("before long reads and after each completed chunk or batch", skill) + self.assertIn("Do not mark that record complete", skill) + self.assertIn("continue from the first unaccounted range", skill) + self.assertIn("reconstruct coverage from verified reusable summaries", skill) + self.assertIn("reread that source from its beginning", skill) + self.assertIn("Summary links are supplemental", skill) self.assertIn("same event key and identical bytes", skill) self.assertIn("Retain and reconcile every distinct-content collision record", skill) self.assertIn("duplicate", skill.lower())