From de8511cfe7ecd39677b758373415c67a4c5709e4 Mon Sep 17 00:00:00 2001 From: divitsheth Date: Sat, 11 Jul 2026 21:32:52 -0700 Subject: [PATCH 01/21] almanac: improve viewer graph links --- almanac/architecture/viewer/local-viewer.md | 6 +++--- almanac/decisions/markdown-links-and-sources.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/almanac/architecture/viewer/local-viewer.md b/almanac/architecture/viewer/local-viewer.md index 68ab5aec..ab31f499 100644 --- a/almanac/architecture/viewer/local-viewer.md +++ b/almanac/architecture/viewer/local-viewer.md @@ -58,9 +58,9 @@ sources: # Local Viewer -The local viewer is the read-only browser surface exposed by `codealmanac serve`. It projects repo wiki pages, topics, file evidence, registered wiki navigation, and lifecycle jobs from local state; it does not own a separate store or write path [@readme] [@viewer_service]. +The local viewer is the read-only browser surface exposed by `codealmanac serve`. It projects repo wiki pages, topics, file evidence, registered wiki navigation, and lifecycle jobs from [local state](../repositories/local-state); it does not own a separate store or write path [@readme] [@viewer_service]. -The command accepts `--wiki`, `--host`, and `--port`, with parser defaults of `127.0.0.1:3927` when host and port are omitted [@parser]. Pages, links, topics, source references, and file references come from the index read model. Job lists and job detail come from the run ledger. The browser routes between those projections with hash routes and renders the current repository's wiki graph [@viewer_service] [@viewer_js]. +The command accepts `--wiki`, `--host`, and `--port`, with parser defaults of `127.0.0.1:3927` when host and port are omitted [@parser]. Pages, links, topics, source references, and file references come from the [index read model](../wiki/index-refresh-and-search). Job lists and job detail come from the [run ledger](../../concepts/run-ledger). The browser routes between those projections with hash routes and renders the current repository's wiki graph [@viewer_service] [@viewer_js]. For the public command contract, see [Public command surface](../../reference/cli/public-command-surface). For the run data shown in the jobs view, see [Run states and events](../../reference/runs/run-states-and-events). @@ -104,6 +104,6 @@ The viewer is intentionally read-only. The architecture tests forbid mutating ru Request validation keeps browser inputs inside the local wiki reference space. File routes normalize repo-relative file and folder references and reject paths that leave that space [@requests]. Server tests cover page, search, file, topic, jobs, registered-wiki switching, 404 mapping for missing pages, 422 mapping for invalid requests, static asset path rejection, and rejection of path-shaped run ids [@server_tests]. -The result is a thin local viewer. It improves navigation and inspection, while the durable contracts remain in the index, run ledger, repository registry, and Markdown page format. +The result is a thin local viewer. It improves navigation and inspection, while the durable contracts remain in the index, run ledger, repository registry, and [Markdown page format](../../reference/page-format/frontmatter-and-sources). For the local files and databases behind those contracts, see [Local state layout](../../reference/local-state-layout). diff --git a/almanac/decisions/markdown-links-and-sources.md b/almanac/decisions/markdown-links-and-sources.md index 81f15284..81a5b96b 100644 --- a/almanac/decisions/markdown-links-and-sources.md +++ b/almanac/decisions/markdown-links-and-sources.md @@ -28,7 +28,7 @@ This decision separates navigation from evidence. A page link points a reader to ## Context -The Python reset replaced older wiki syntax with a simpler authored format. The base writer prompt tells agents to use Markdown links such as `[Viewer](../viewer)`, link only to existing or newly created pages, cite non-obvious claims with inline source markers, and store file/folder evidence in `sources:` [@kernel]. +The Python reset replaced older wiki syntax with a simpler authored format. The base writer prompt tells agents to use Markdown links such as `[Local viewer](../architecture/viewer/local-viewer)`, link only to existing or newly created pages, cite non-obvious claims with inline source markers, and store file/folder evidence in `sources:` [@kernel]. The sources canonical plan made structured `sources:` the only authored evidence model for file-aware retrieval. It removed legacy file-list parsing and kept file references derived from `sources[type=file]` [@sources_plan]. That means evidence is no longer split between old frontmatter fields and current source records. From 34c502d42f20024a2c6813c6d36aae0f3637dee7 Mon Sep 17 00:00:00 2001 From: divitsheth Date: Sat, 11 Jul 2026 23:31:20 -0700 Subject: [PATCH 02/21] almanac: record launch video positioning --- .../demo-codealmanac-in-launch-video.md | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/almanac/guides/demo-codealmanac-in-launch-video.md b/almanac/guides/demo-codealmanac-in-launch-video.md index b6e56235..7607e7f6 100644 --- a/almanac/guides/demo-codealmanac-in-launch-video.md +++ b/almanac/guides/demo-codealmanac-in-launch-video.md @@ -14,6 +14,14 @@ sources: type: web url: https://github.com/bcurts/agentchattr note: Local multi-agent chat comparison point. + - id: launch-video-session + type: conversation + path: /Users/divitsheth/.codex/sessions/2026/07/09/rollout-2026-07-09T19-26-19-019f49d8-e706-7d73-9fa0-1cd8009b02cb.jsonl + note: Launch-video implementation session and follow-up scope check. + - id: product-positioning-session + type: conversation + path: /Users/divitsheth/.codex/sessions/2026/07/11/rollout-2026-07-11T19-18-29-019f541e-72eb-7e01-8644-b2a5e139fcd7.jsonl + note: Product-origin and three-pillar positioning discussion. --- # Demo CodeAlmanac In A Launch Video @@ -42,6 +50,29 @@ decisions, invariants, gotchas, flows, and operating knowledge that future agent sessions would otherwise rediscover. Git keeps that knowledge reviewable, while build, ingest, garden, and sync keep it current [@public-readme]. +Keep launch-video claims local to the current product. The companion feature +video covers ingest, background jobs, session sync, Garden maintenance, and +local-only automation; it does not mention a hosted product, PR automation, +GitHub workflows, or cloud features [@launch-video-session]. + +Use three plain pillars when explaining how CodeAlmanac solves the context +problem: + +1. **Updates from conversations:** CodeAlmanac reads coding-agent conversations + and saves decisions, rejected ideas, bug lessons, and other context the code + does not explain [@product-positioning-session]. +2. **Made for agents:** The wiki is a set of connected Markdown pages, so + agents can search for relevant context instead of reading one large + instruction file [@product-positioning-session]. +3. **Gardens itself:** CodeAlmanac regularly checks and reorganizes the wiki, + removing stale information as the codebase changes [@product-positioning-session]. + +Keep the wording direct and a little imperfect. The approved origin story is +that this problem appeared while building OpenAlmanac and earlier products with +coding agents: decisions, rejected approaches, and lessons kept disappearing +between sessions, so agents repeated old mistakes or changed code without +understanding why it had its shape [@product-positioning-session]. + Team-chat tools such as TagIt and agentchattr route work and conversation among agents [@tagit] [@agentchattr]. They are adjacent rather than equivalent: CodeAlmanac's primary artifact is the maintained repository wiki that later From 04c632d335e8afce971b4d83cfcf06883a61b106 Mon Sep 17 00:00:00 2001 From: divitsheth Date: Sun, 12 Jul 2026 16:24:44 -0700 Subject: [PATCH 03/21] almanac: add public launch notes --- .../demo-codealmanac-in-launch-video.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/almanac/guides/demo-codealmanac-in-launch-video.md b/almanac/guides/demo-codealmanac-in-launch-video.md index 7607e7f6..7f0becd2 100644 --- a/almanac/guides/demo-codealmanac-in-launch-video.md +++ b/almanac/guides/demo-codealmanac-in-launch-video.md @@ -22,6 +22,10 @@ sources: type: conversation path: /Users/divitsheth/.codex/sessions/2026/07/11/rollout-2026-07-11T19-18-29-019f541e-72eb-7e01-8644-b2a5e139fcd7.jsonl note: Product-origin and three-pillar positioning discussion. + - id: show-hn + type: web + url: https://news.ycombinator.com/item?id=48849361 + note: Initial Show HN post for CodeAlmanac. --- # Demo CodeAlmanac In A Launch Video @@ -77,3 +81,18 @@ Team-chat tools such as TagIt and agentchattr route work and conversation among agents [@tagit] [@agentchattr]. They are adjacent rather than equivalent: CodeAlmanac's primary artifact is the maintained repository wiki that later agents query before changing code, not a chat channel between agents. + +## Public Launch Notes + +When answering public launch questions, be transparent that CodeAlmanac already +had an initial Show HN on July 9, 2026 [@show-hn]. The later Launch HN should +be framed as a fuller introduction to the same local, open-source CLI rather +than as a major product-change announcement [@product-positioning-session]. + +The concise answer for a missing demo video is that HN users can install and +try the CLI directly without creating an account [@product-positioning-session]. +Keep privacy claims tied to the local product boundary: the CLI has no Almanac +account, telemetry, analytics, or usage tracking; user code, transcripts, and +wiki content stay local except for the selected model provider used by the +user's own Codex or Claude account during lifecycle runs [@public-readme] +[@product-positioning-session]. From b6afe305609afe2165f829394e56bba2d2a5e00c Mon Sep 17 00:00:00 2001 From: divitsheth Date: Sun, 12 Jul 2026 17:30:13 -0700 Subject: [PATCH 04/21] almanac: improve garden evidence and yoke topics --- .../agent-runs/provider-adapters.md | 2 +- ...filiation-belongs-in-repository-service.md | 24 +++++----- .../demo-codealmanac-in-launch-video.md | 48 +++++++++---------- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/almanac/architecture/agent-runs/provider-adapters.md b/almanac/architecture/agent-runs/provider-adapters.md index 3ae6b52e..7a0c0032 100644 --- a/almanac/architecture/agent-runs/provider-adapters.md +++ b/almanac/architecture/agent-runs/provider-adapters.md @@ -1,6 +1,6 @@ --- title: Yoke Harness Boundary -topics: [architecture, harnesses, providers, agent-runs] +topics: [architecture, harnesses, providers, agent-runs, yoke] sources: - id: adapter type: file diff --git a/almanac/decisions/repository-affiliation-belongs-in-repository-service.md b/almanac/decisions/repository-affiliation-belongs-in-repository-service.md index acfd74af..f41d5fef 100644 --- a/almanac/decisions/repository-affiliation-belongs-in-repository-service.md +++ b/almanac/decisions/repository-affiliation-belongs-in-repository-service.md @@ -2,10 +2,6 @@ title: Repository Affiliation Belongs In Repository Service topics: [decisions, repositories, lifecycle] sources: - - id: affiliation-transcript - type: conversation - path: /Users/rohan/.codex/sessions/2026/07/10/rollout-2026-07-10T16-35-11-019f4e62-96e5-7212-82fa-013a204a6c50.jsonl - note: Architecture discussion that reframed Conductor/worktree support as repository affiliation. - id: repository-service type: file path: src/codealmanac/services/repositories/service.py @@ -18,11 +14,15 @@ sources: type: file path: src/codealmanac/workflows/sync/service.py note: Sync workflow that discovers transcripts and queues ingest. + - id: service-boundaries + type: wiki + path: architecture/service-boundaries + note: Boundary rule that product verbs live in services and outside systems sit behind service-owned ports. --- # Repository Affiliation Belongs In Repository Service -Repository affiliation is the proposed boundary for mapping an artifact created in a checkout back to the canonical registered CodeAlmanac repository. The problem first appeared as support for Conductor workspaces, but the durable design issue is broader: a transcript can be created in a temporary checkout, worktree, or nested directory that is not the exact registered repository root [@affiliation-transcript]. The repository service should own that decision because it already owns registered repository identity and selection [@repository-service]. +Repository affiliation is the proposed boundary for mapping an artifact created in a checkout back to the canonical registered CodeAlmanac repository. The durable design issue is broader than one workspace tool: a transcript can be created from a checkout path that is not the exact registered repository root. The repository service should own that decision because it already owns registered repository identity and selection [@repository-service] [@service-boundaries]. ## Status @@ -30,22 +30,22 @@ Proposed. No `resolve_affiliation` method or checkout inspector exists in `src/c ## Context -Current repository selection is exact. `select_for_operation(...)` uses the current directory as the repository only when it is the exact registered root, and named selection goes through the repository registry [@repository-service]. The selection helpers compare exact normalized paths and validate containment, but they do not identify two checkouts as the same underlying Git repository [@repository-selection]. +Current repository selection is exact. `select_for_operation(...)` uses the current directory as the repository only when it is the exact registered root, and named selection goes through the repository registry [@repository-service]. The selection helpers compare exact normalized paths and validate containment, but they do not identify two checkouts as the same underlying repository [@repository-selection]. -That model works for ordinary runs from the registered checkout. It breaks down when sync sees a transcript whose working directory was a worktree or other temporary checkout. The transcript path is an artifact location, not necessarily the product repository identity [@affiliation-transcript]. +That model works for ordinary runs from the registered checkout. It is the wrong place to solve future transcript-checkout matching by weakening exact root selection, because selection and path containment are current repository-service mechanics [@repository-service] [@repository-selection]. ## Decision -Treat affiliation as a repository-service operation, not as Conductor-specific logic. The intended shape is a service method such as `repositories.resolve_affiliation(path)` returning the canonical registered repository, the observed checkout path, and the match method [@affiliation-transcript]. +Treat affiliation as a repository-service operation, not as sync-specific or provider-specific logic. The intended shape is a repository service method that accepts an observed path and returns the canonical registered repository plus enough match information for callers to explain the result [@repository-service] [@service-boundaries]. -Git should be an integration detail behind a service-owned port. The proposed first implementation uses a checkout inspector that reads Git common-dir identity, so ordinary exact-path matching remains the fast path and Git worktree matching is an additional affiliation method [@affiliation-transcript]. +Git or filesystem inspection should be an integration detail behind a service-owned port. Ordinary exact-path matching should remain the fast path; any richer checkout matching should add a separate affiliation path instead of changing what exact repository selection means [@repository-selection] [@service-boundaries]. ## Consequences -Sync should ask the repository service which registered repository owns a transcript working directory, then queue ingest against that repository. Sync should not recognize Conductor path patterns, compare remote URLs, register every worktree, or treat branch names as repository identity [@affiliation-transcript] [@sync-workflow]. +Sync should ask the repository service which registered repository owns a transcript working directory, then queue ingest against that repository. Sync should not grow its own repository identity rules, because it is already a scanner that delegates page-writing work to ordinary ingest runs [@sync-workflow] [@service-boundaries]. -Ambiguity must be explicit. If two registered roots share one Git common-dir identity, CodeAlmanac should report ambiguous affiliation rather than guess [@affiliation-transcript]. Deleted temporary checkouts are out of scope for the first version because a deleted path can no longer reveal its Git identity; caching observed checkout affiliations would need separate invalidation rules [@affiliation-transcript]. +Ambiguity must be explicit. If a future affiliation implementation can match more than one registered repository, CodeAlmanac should report ambiguity rather than guess. That keeps repository identity a product decision instead of a side effect of sync discovery [@repository-service] [@service-boundaries]. -This decision does not change `repository_id_for(...)`. The transcript explicitly separates the affiliation seam from durable repository identity migration: the repository id can remain based on the registered filesystem path until relocation becomes its own design problem [@affiliation-transcript]. +This decision does not change `repository_id_for(...)` or the current exact-root registry model. Repository id migration and repository relocation are separate design problems; affiliation is only the future seam for mapping observed artifact paths back to registered repositories [@repository-service] [@repository-selection]. For the current exact-root behavior, see [Repository Selection And Root](../architecture/repositories/selection-and-root). For the queue boundary that sync feeds, see [Run Queue And Sync](../architecture/lifecycle/run-queue-and-sync). diff --git a/almanac/guides/demo-codealmanac-in-launch-video.md b/almanac/guides/demo-codealmanac-in-launch-video.md index 7f0becd2..4cd9d4f4 100644 --- a/almanac/guides/demo-codealmanac-in-launch-video.md +++ b/almanac/guides/demo-codealmanac-in-launch-video.md @@ -14,14 +14,14 @@ sources: type: web url: https://github.com/bcurts/agentchattr note: Local multi-agent chat comparison point. - - id: launch-video-session - type: conversation - path: /Users/divitsheth/.codex/sessions/2026/07/09/rollout-2026-07-09T19-26-19-019f49d8-e706-7d73-9fa0-1cd8009b02cb.jsonl - note: Launch-video implementation session and follow-up scope check. - - id: product-positioning-session - type: conversation - path: /Users/divitsheth/.codex/sessions/2026/07/11/rollout-2026-07-11T19-18-29-019f541e-72eb-7e01-8644-b2a5e139fcd7.jsonl - note: Product-origin and three-pillar positioning discussion. + - id: live-agreement + type: file + path: docs/python-port-live-agreement.md + note: Local-only product boundary and excluded hosted/cloud surfaces. + - id: differentiation + type: file + path: docs/strategy/codealmanac-vs-deepwiki-supermemory.md + note: Product positioning around git-native repo memory maintained by agents. - id: show-hn type: web url: https://news.ycombinator.com/item?id=48849361 @@ -54,28 +54,27 @@ decisions, invariants, gotchas, flows, and operating knowledge that future agent sessions would otherwise rediscover. Git keeps that knowledge reviewable, while build, ingest, garden, and sync keep it current [@public-readme]. -Keep launch-video claims local to the current product. The companion feature -video covers ingest, background jobs, session sync, Garden maintenance, and -local-only automation; it does not mention a hosted product, PR automation, -GitHub workflows, or cloud features [@launch-video-session]. +Keep launch-video claims local to the current product. The Python rewrite is a +local-only CLI and explicitly excludes hosted shipping, login/connect/upload, +SDK, MCP, and cloud capture surfaces in this version [@live-agreement]. Use three plain pillars when explaining how CodeAlmanac solves the context problem: 1. **Updates from conversations:** CodeAlmanac reads coding-agent conversations and saves decisions, rejected ideas, bug lessons, and other context the code - does not explain [@product-positioning-session]. + does not explain [@public-readme] [@differentiation]. 2. **Made for agents:** The wiki is a set of connected Markdown pages, so - agents can search for relevant context instead of reading one large - instruction file [@product-positioning-session]. + agents can search for relevant context before changing the repo [@public-readme] + [@differentiation]. 3. **Gardens itself:** CodeAlmanac regularly checks and reorganizes the wiki, - removing stale information as the codebase changes [@product-positioning-session]. + reducing stale, duplicated, or poorly connected knowledge [@public-readme] + [@differentiation]. -Keep the wording direct and a little imperfect. The approved origin story is -that this problem appeared while building OpenAlmanac and earlier products with -coding agents: decisions, rejected approaches, and lessons kept disappearing -between sessions, so agents repeated old mistakes or changed code without -understanding why it had its shape [@product-positioning-session]. +Keep the wording direct and a little imperfect. The durable story is that +CodeAlmanac is a git-native living wiki for one codebase, maintained by coding +agents as a side effect of real development and optimized for the next coding +agent before it edits the repo [@differentiation]. Team-chat tools such as TagIt and agentchattr route work and conversation among agents [@tagit] [@agentchattr]. They are adjacent rather than equivalent: @@ -87,12 +86,13 @@ agents query before changing code, not a chat channel between agents. When answering public launch questions, be transparent that CodeAlmanac already had an initial Show HN on July 9, 2026 [@show-hn]. The later Launch HN should be framed as a fuller introduction to the same local, open-source CLI rather -than as a major product-change announcement [@product-positioning-session]. +than as a major product-change announcement [@public-readme] [@live-agreement]. The concise answer for a missing demo video is that HN users can install and -try the CLI directly without creating an account [@product-positioning-session]. +try the CLI directly without creating an account [@public-readme] +[@live-agreement]. Keep privacy claims tied to the local product boundary: the CLI has no Almanac account, telemetry, analytics, or usage tracking; user code, transcripts, and wiki content stay local except for the selected model provider used by the user's own Codex or Claude account during lifecycle runs [@public-readme] -[@product-positioning-session]. +[@live-agreement]. From aa999402d26b496a009c6c749fa3df772e1a16e5 Mon Sep 17 00:00:00 2001 From: divitsheth Date: Sun, 12 Jul 2026 21:34:17 -0700 Subject: [PATCH 05/21] almanac: add leads for runtime resource pages --- .../architecture/agent-runs/provider-adapters.md | 10 ++++++++++ .../runtime-resources/prompts-and-manuals.md | 13 ++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/almanac/architecture/agent-runs/provider-adapters.md b/almanac/architecture/agent-runs/provider-adapters.md index 7a0c0032..f1ddfa08 100644 --- a/almanac/architecture/agent-runs/provider-adapters.md +++ b/almanac/architecture/agent-runs/provider-adapters.md @@ -30,6 +30,16 @@ sources: # Yoke Harness Boundary +The Yoke harness boundary is CodeAlmanac's adapter layer for running lifecycle +agents through the service-owned harness contract. `YokeHarnessAdapter` binds +build, ingest, and garden prompts to Claude or Codex through Yoke, projects +provider events into CodeAlmanac `HarnessEvent` records, and returns normalized +`HarnessRunResult` values to lifecycle workflows [@adapter] [@events] +[@results] [@contract]. The boundary matters because provider runtime details, +caches, readiness checks, permissions, and failures stay under local state and +integration code instead of leaking into workflows or wiki-writing prompts +[@adapter] [@defaults] [@app]. + ## What It Owns CodeAlmanac has one provider integration: `YokeHarnessAdapter`. It implements diff --git a/almanac/architecture/runtime-resources/prompts-and-manuals.md b/almanac/architecture/runtime-resources/prompts-and-manuals.md index 97572afa..0a15f6b8 100644 --- a/almanac/architecture/runtime-resources/prompts-and-manuals.md +++ b/almanac/architecture/runtime-resources/prompts-and-manuals.md @@ -1,6 +1,6 @@ --- title: Agents And Manuals -topics: [architecture, runtime-resources, manuals, yoke] +topics: [architecture, runtime-resources, manuals, prompts, yoke] sources: - id: catalog type: file @@ -42,6 +42,17 @@ sources: # Agents And Manuals +Agents and manuals are CodeAlmanac's packaged runtime resources for lifecycle +wiki-writing operations. Build, ingest, and garden are stable agents in a Yoke +collection, while shared writing references remain packaged manual documents +that workflows either copy into `almanac/manual/` or embed in a typed runtime +payload [@catalog] [@collection] [@manual-library] [@build-service] +[@ingest-service] [@garden-service]. This boundary keeps durable instructions, +per-run facts, and provider execution separate: agent folders own the operation +instructions, workflow services own the JSON runtime context, and the Yoke +adapter loads the selected agent at execution time [@build-agent] +[@ingest-agent] [@garden-agent]. + ## What It Owns Build, ingest, and garden are a packaged Yoke `Collection`. The collection From e2f1e4ff69bb3362e7a7816054ad27cc16d91814 Mon Sep 17 00:00:00 2001 From: divitsheth Date: Sun, 12 Jul 2026 21:46:08 -0700 Subject: [PATCH 06/21] almanac: record wiki evaluation and harness review learnings --- .../setup/automation-and-update.md | 6 ++ almanac/concepts/README.md | 8 +++ .../concepts/wiki-usefulness-evaluation.md | 62 +++++++++++++++++++ .../guides/add-a-harness-provider-adapter.md | 19 ++++-- 4 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 almanac/concepts/wiki-usefulness-evaluation.md diff --git a/almanac/architecture/setup/automation-and-update.md b/almanac/architecture/setup/automation-and-update.md index 8524cafb..7c0bc73e 100644 --- a/almanac/architecture/setup/automation-and-update.md +++ b/almanac/architecture/setup/automation-and-update.md @@ -34,6 +34,10 @@ sources: type: file path: src/codealmanac/services/updates/service.py note: Manual and scheduled package update behavior. + - id: update_lock + type: file + path: src/codealmanac/services/updates/lock.py + note: PID-file update lock implementation. - id: update_metadata type: file path: src/codealmanac/integrations/updates/package.py @@ -78,6 +82,8 @@ Manual update and scheduled update share the same planning logic. `plan_update` Scheduled update adds safety checks before running the package command. It skips if the install is not ready, if an update lock is already held, or if the local database shows active CodeAlmanac jobs [@updates]. After a successful scheduled package update, it runs two smoke checks: `codealmanac --version` and `codealmanac doctor --json` [@updates]. Tests cover the uv and pip plans, editable-install refusal, active-job skip, held-lock skip, smoke success, and smoke failure paths [@update_tests]. +The current update lock is a PID-file lease. `UpdateLockStore.acquire` writes a JSON record with the current PID and timestamp using exclusive file creation, treats old records as stale, unlinks stale files, then tries once more [@update_lock]. Because the replacement of a stale file is not an OS-backed lock held for the full update, future changes to update concurrency should prefer a real process lock and prove that a second process cannot enter while the first still owns the update [@update_lock][@update_tests]. + The editable-install guard does not cover every PEP 610 direct-url install. The metadata reader records `source_url` from `direct_url.json`, but `update_method` only uses the `editable` flag before falling through to the installer-based uv or pip plan [@update_metadata][@updates]. A non-editable local path, VCS, or direct archive install with `INSTALLER` set to `uv` or `pip` can therefore still be upgraded through the normal package command. This shape matches the active agreement: scheduled auto-update is an explicit local automation task, not a sync or Garden side effect. The agreement also states that scheduled update should skip editable installs, skip active lifecycle jobs, use a global lock, support uv tool and pip installs, and run the same two smoke checks [@live_agreement]. diff --git a/almanac/concepts/README.md b/almanac/concepts/README.md index 14c5bf20..222181f4 100644 --- a/almanac/concepts/README.md +++ b/almanac/concepts/README.md @@ -26,6 +26,10 @@ sources: type: wiki path: concepts/page-graph note: Concept page for the derived page, topic, link, source, and health graph. + - id: wiki-usefulness-evaluation + type: wiki + path: concepts/wiki-usefulness-evaluation + note: Concept page for evaluating whether the wiki improves agent work. --- # Concepts @@ -52,6 +56,10 @@ topics, links, file references, sources, backlinks, and health checks today without being a validated frontmatter field is a product decision; see [No page-kind field](../decisions/no-page-kind-field). +[Wiki usefulness evaluation](wiki-usefulness-evaluation) defines the product +standard for judging whether the wiki helps agents complete real codebase work, +instead of only scoring page cleanliness or graph shape [@wiki-usefulness-evaluation]. + ## Lifecycle And Inputs [Lifecycle operation](lifecycle-operation) defines build, ingest, and garden as diff --git a/almanac/concepts/wiki-usefulness-evaluation.md b/almanac/concepts/wiki-usefulness-evaluation.md new file mode 100644 index 00000000..d24e59b6 --- /dev/null +++ b/almanac/concepts/wiki-usefulness-evaluation.md @@ -0,0 +1,62 @@ +--- +title: Wiki Usefulness Evaluation +topics: [concepts, wiki, product] +sources: + - id: eval-discussion + type: conversation + path: /Users/divitsheth/.codex/sessions/2026/07/12/rollout-2026-07-12T17-29-11-019f58e0-bc84-7da3-a822-8e610a1935d8.jsonl + note: Product discussion that framed useful wiki evaluation around agent task outcomes. + - id: local-repo-wiki + type: wiki + path: concepts/local-repo-wiki + note: Concept page for the repo-owned Markdown wiki model. +--- + +# Wiki Usefulness Evaluation + +Wiki usefulness evaluation asks whether the [local repo wiki](local-repo-wiki) +helps an agent complete real codebase work better. The primary score is not +page tidiness. It is whether an agent with the wiki succeeds more often, makes +fewer architecture mistakes, spends less time or token budget, and needs less +review rework than an agent using the codebase alone [@eval-discussion] +[@local-repo-wiki]. + +The concept matters because CodeAlmanac can measure many tidy proxies without +proving product value. A wiki can have healthy links, citations, and topics and +still fail to help a future agent make the right change. The useful evaluation +therefore starts from real work, then uses retrieval and page-quality checks as +diagnostics [@eval-discussion]. + +## Primary Signal + +The strongest evaluation compares realistic tasks under two conditions: codebase +only, and codebase plus Almanac. The task set should include implementation, +debugging, architecture choice, and repository-knowledge questions. Useful +measurements include success rate, correctness, files opened before the agent +understands the task, tokens or elapsed time, review findings, and repeated +violations of documented invariants [@eval-discussion]. + +This turns the evaluation into a product question: did the wiki improve the +agent's work? It also discourages optimizing the wiki only for clean formatting +or dense coverage [@eval-discussion]. + +## Supporting Diagnostics + +Question-answer tests check whether the wiki preserves repository knowledge +that is hard to infer from code alone. Good prompts ask where provider-specific +logic belongs, which operations may write wiki prose, why path queries use +escaped `GLOB`, or how an ingest run moves through the system [@eval-discussion]. + +Decision-support tests check whether the wiki teaches engineering judgment. +The evaluator should look for correct boundary choices, noticed invariants, +rejection of tempting one-off fixes, and explanations grounded in the right +pages and source files [@eval-discussion]. + +Retrieval metrics diagnose whether search surfaces the right pages. Useful +measures include recall, precision, ranking, context efficiency, and robustness +when the same task is phrased different ways [@eval-discussion]. + +Page-quality metrics remain valuable, but they are secondary. Accuracy against +code, staleness, actionability, specificity, evidence quality, duplication, +contradictions, link health, and coverage of important flows explain why the +wiki helped or failed to help during task evaluation [@eval-discussion]. diff --git a/almanac/guides/add-a-harness-provider-adapter.md b/almanac/guides/add-a-harness-provider-adapter.md index 62596235..b16f6949 100644 --- a/almanac/guides/add-a-harness-provider-adapter.md +++ b/almanac/guides/add-a-harness-provider-adapter.md @@ -2,6 +2,10 @@ title: Add A Harness Provider Adapter topics: [guides, harnesses, yoke] sources: + - id: pyproject + type: file + path: pyproject.toml + note: Yoke package dependency used by the harness adapter. - id: adapter type: file path: src/codealmanac/integrations/harnesses/yoke/adapter.py @@ -37,8 +41,10 @@ If the provider or surface CodeAlmanac needs does not exist yet, add it in Yoke, not in this repo. CodeAlmanac does not implement its own provider protocol adapter [@adapter]. Yoke owns authentication, provider processes, native surface options, skills, subagents, sessions, models, and normalized provider events. -Prove the feature against the real provider in Yoke before changing CodeAlmanac. -Do not reproduce SDK or JSON-RPC behavior under `integrations/harnesses/`. +Prove the feature against the real provider in Yoke before changing CodeAlmanac, +then require a released Yoke version that contains that provider in +`pyproject.toml` [@pyproject]. Do not reproduce SDK or JSON-RPC behavior under +`integrations/harnesses/`. ## Add The Product Choice In CodeAlmanac @@ -65,9 +71,12 @@ on provider names [@events]. Add focused boundary tests for readiness, exact task forwarding, model and agent selection, callbacks, failures, event serialization, and any new display -facts [@tests]. Then run the real provider surface, the affected lifecycle -operation, the full test suite, Ruff, wheel/sdist builds, Twine checks, and a -fresh installed-wheel smoke. +facts [@tests]. Once a provider is added to `HarnessKind`, tests must assert that +`create_yoke_harness(...)` starts for that provider with the pinned Yoke release +instead of skipping when Yoke lacks the enum or surface [@kinds] [@adapter] +[@pyproject] [@tests]. Then run the real provider surface, the affected +lifecycle operation, the full test suite, Ruff, wheel/sdist builds, Twine +checks, and a fresh installed-wheel smoke. Related architecture: [Yoke harness boundary](../architecture/agent-runs/provider-adapters) and [Agents and manuals](../architecture/runtime-resources/prompts-and-manuals). From 7e593ffa1b17586be19125919b0a8b21b88e080d Mon Sep 17 00:00:00 2001 From: divitsheth Date: Mon, 13 Jul 2026 12:13:20 -0700 Subject: [PATCH 07/21] almanac: record update lock release race --- almanac/architecture/setup/automation-and-update.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/almanac/architecture/setup/automation-and-update.md b/almanac/architecture/setup/automation-and-update.md index 7c0bc73e..bcebb0bc 100644 --- a/almanac/architecture/setup/automation-and-update.md +++ b/almanac/architecture/setup/automation-and-update.md @@ -46,6 +46,10 @@ sources: type: file path: tests/test_update_service.py note: Tests for update planning, skip rules, locks, and smoke checks. + - id: filelock_review + type: conversation + path: "/Users/divitsheth/.codex/sessions/2026/07/12/rollout-2026-07-12T18-18-36-019f590d-fa0d-75d3-811f-0044dc0a138f.jsonl" + note: Review discussion of a FileLock-based update-lock replacement. - id: live_agreement type: file path: docs/python-port-live-agreement.md @@ -84,6 +88,8 @@ Scheduled update adds safety checks before running the package command. It skips The current update lock is a PID-file lease. `UpdateLockStore.acquire` writes a JSON record with the current PID and timestamp using exclusive file creation, treats old records as stale, unlinks stale files, then tries once more [@update_lock]. Because the replacement of a stale file is not an OS-backed lock held for the full update, future changes to update concurrency should prefer a real process lock and prove that a second process cannot enter while the first still owns the update [@update_lock][@update_tests]. +If the lock is replaced with FileLock or another file-locking library, the release path should let the library own the lock file instead of deleting it after release. The reviewed FileLock replacement showed why: a process can acquire after the release call and before the manual deletion, then another process can create a new lock file while the acquired process still holds the old file descriptor [@filelock_review]. Tests for that shape should assert that another process can acquire after release, not that the lock file disappears; once timestamp staleness is gone, `now`, `stale_after`, and `lock_stale_after` should be removed from the update path instead of kept as unused request plumbing [@filelock_review][@setup_requests]. + The editable-install guard does not cover every PEP 610 direct-url install. The metadata reader records `source_url` from `direct_url.json`, but `update_method` only uses the `editable` flag before falling through to the installer-based uv or pip plan [@update_metadata][@updates]. A non-editable local path, VCS, or direct archive install with `INSTALLER` set to `uv` or `pip` can therefore still be upgraded through the normal package command. This shape matches the active agreement: scheduled auto-update is an explicit local automation task, not a sync or Garden side effect. The agreement also states that scheduled update should skip editable installs, skip active lifecycle jobs, use a global lock, support uv tool and pip installs, and run the same two smoke checks [@live_agreement]. From 5cb3868210c9a329a846aa87ee0ee23d0d8de37c Mon Sep 17 00:00:00 2001 From: divitsheth Date: Mon, 13 Jul 2026 15:44:52 -0700 Subject: [PATCH 08/21] almanac: tighten lifecycle and hub routes --- almanac/architecture/lifecycle/README.md | 6 +++++- almanac/architecture/lifecycle/workflows.md | 2 +- almanac/decisions/README.md | 8 ++++++++ almanac/guides/README.md | 8 ++++++++ almanac/guides/release-package.md | 2 +- 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/almanac/architecture/lifecycle/README.md b/almanac/architecture/lifecycle/README.md index a140a78a..33dce9a5 100644 --- a/almanac/architecture/lifecycle/README.md +++ b/almanac/architecture/lifecycle/README.md @@ -30,6 +30,10 @@ sources: type: wiki path: reference/runs/run-states-and-events note: Reference page for run kinds, statuses, specs, events, and logs. + - id: agents-manuals + type: wiki + path: architecture/runtime-resources/prompts-and-manuals + note: Architecture page for packaged Yoke agents and writing manuals used by lifecycle operations. --- # Lifecycle @@ -50,4 +54,4 @@ Use [Mutation safety](mutation-safety) when changing allowed files, auto-commit ## Neighboring Pages -[Run states and events](../../reference/runs/run-states-and-events) is the exact reference for run kinds, statuses, queued specs, cancellation, attach, and logs [@run-states]. [Lifecycle operation](../../concepts/lifecycle-operation) is the concept page for the page-writing operation family [@lifecycle-concept]. +[Run states and events](../../reference/runs/run-states-and-events) is the exact reference for run kinds, statuses, queued specs, cancellation, attach, and logs [@run-states]. [Lifecycle operation](../../concepts/lifecycle-operation) is the concept page for the page-writing operation family [@lifecycle-concept]. [Agents and manuals](../runtime-resources/prompts-and-manuals) explains the packaged Yoke agents and writing manuals that lifecycle workflows bind into page-writing runs [@agents-manuals]. diff --git a/almanac/architecture/lifecycle/workflows.md b/almanac/architecture/lifecycle/workflows.md index 55bf69f0..fe11aa3c 100644 --- a/almanac/architecture/lifecycle/workflows.md +++ b/almanac/architecture/lifecycle/workflows.md @@ -34,7 +34,7 @@ The workflows prepare operation-specific context, but they do not each own harne Build is the initialization workflow. At queue time, it prepares a repository target, rejects an existing `almanac/`, registers the repository, initializes a minimal wiki, and records a queued build run [@build-workflow]. Harness readiness is checked later by the worker through the shared operation path, not before the initial wiki scaffold is written. -When the worker executes the queued run, build calls the shared operation runner. Its task payload includes repository paths, the almanac root, `topics.yaml`, manual documents, optional guidance, and source-control policy [@build-workflow]. The stable instructions come from the packaged build agent described in [Agents and manuals](../runtime-resources/prompts-and-manuals). Build is therefore both setup and the first agent-authored wiki pass. +When the worker executes the queued run, build calls the shared operation runner. Its task payload includes repository paths, the almanac root, `topics.yaml`, the repository-local manual root, optional guidance, and source-control policy [@build-workflow]. The stable instructions come from the packaged build agent described in [Agents and manuals](../runtime-resources/prompts-and-manuals). Build is therefore both setup and the first agent-authored wiki pass. ## Ingest diff --git a/almanac/decisions/README.md b/almanac/decisions/README.md index a6dec52c..8320e074 100644 --- a/almanac/decisions/README.md +++ b/almanac/decisions/README.md @@ -34,6 +34,10 @@ sources: type: wiki path: decisions/controlled-model-catalog note: Decision that keeps supported harness models in a controlled catalog. + - id: repository-affiliation + type: wiki + path: decisions/repository-affiliation-belongs-in-repository-service + note: Decision that keeps future transcript checkout affiliation under the repository service boundary. --- # Decisions @@ -56,6 +60,10 @@ and machine-local runtime state [@local-only]. root: `almanac/`. It rejects `.almanac/`, `docs/almanac/`, custom roots, and root migration shims as current product surfaces [@root]. +[Repository affiliation belongs in repository service](repository-affiliation-belongs-in-repository-service) +records the future ownership boundary for mapping artifacts from checkout paths +back to registered repositories [@repository-affiliation]. + ## Wiki Format [Markdown links and sources](markdown-links-and-sources) decides that page diff --git a/almanac/guides/README.md b/almanac/guides/README.md index 48e16959..b5e6c26d 100644 --- a/almanac/guides/README.md +++ b/almanac/guides/README.md @@ -26,6 +26,10 @@ sources: type: wiki path: guides/setup-local-automation note: Procedure for setting up local scheduled automation. + - id: release-package + type: wiki + path: guides/release-package + note: Procedure for publishing and verifying the Python package release. - id: topics-guide type: wiki path: guides/maintain-topics @@ -73,6 +77,10 @@ path for build, ingest, or garden jobs that fail through the run queue entries, sync and garden cadence, update checks, and verification for local automation [@automation]. +[Release package](release-package) covers PyPI publishing, installed-artifact +smoke checks, public install verification, and package-surface rules +[@release-package]. + ## Maintain The Wiki [Verify a wiki change](verify-a-wiki-change) is the shortest validation path diff --git a/almanac/guides/release-package.md b/almanac/guides/release-package.md index 9928378d..969f51ab 100644 --- a/almanac/guides/release-package.md +++ b/almanac/guides/release-package.md @@ -5,7 +5,7 @@ sources: - id: release-doc type: file path: RELEASE.md - note: Python package release checklist and package-surface rules. + note: Python package release checklist and public-surface constraints; package data is cross-checked against pyproject.toml. - id: pyproject type: file path: pyproject.toml From eea2a2310b9fe81005d8bc574a4eeea58675ebd6 Mon Sep 17 00:00:00 2001 From: divitsheth Date: Mon, 13 Jul 2026 18:16:49 -0700 Subject: [PATCH 09/21] almanac: document setup platform boundary --- .../architecture/setup/automation-and-update.md | 2 +- almanac/guides/setup-local-automation.md | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/almanac/architecture/setup/automation-and-update.md b/almanac/architecture/setup/automation-and-update.md index bcebb0bc..06394d2e 100644 --- a/almanac/architecture/setup/automation-and-update.md +++ b/almanac/architecture/setup/automation-and-update.md @@ -78,7 +78,7 @@ The job factory gives each task concrete local execution details. The resolved ` The macOS implementation writes launchd plists under `~/Library/LaunchAgents`, creates stdout and stderr log directories, bootouts any existing job, bootstraps the new job, and reads status back from launchd [@launchd]. The generated plist contains the label, program arguments, start interval, environment variables, `RunAtLoad`, and log paths [@launchd]. This keeps the service boundary scheduler-neutral while the adapter owns launchd mechanics. -The default application wiring is launchd-backed. `create_services` constructs `AutomationService` with `LaunchdSchedulerAdapter`, then injects it into the config service. The adapter shells out to `launchctl` for install, uninstall, and status checks [@app][@launchd]. Config reconciliation is macOS-specific until another scheduler adapter is wired. +The default application wiring is launchd-backed. `create_services` constructs `AutomationService` with `LaunchdSchedulerAdapter`, then injects it into the config service. The adapter shells out to `launchctl` for install, uninstall, and status checks [@app][@launchd]. Config reconciliation is macOS-specific until another scheduler adapter is wired. There is no platform-selection branch in the composition root, so setup on a machine without `launchctl` reaches the launchd adapter and surfaces a scheduler execution failure instead of selecting a Linux or Windows scheduler [@app][@launchd]. ## Update Safety diff --git a/almanac/guides/setup-local-automation.md b/almanac/guides/setup-local-automation.md index e0fe26f4..7c2cc114 100644 --- a/almanac/guides/setup-local-automation.md +++ b/almanac/guides/setup-local-automation.md @@ -26,6 +26,14 @@ sources: type: file path: src/codealmanac/services/setup/service.py note: Setup service behavior for instructions, config, automation, readiness, and uninstall. + - id: app + type: file + path: src/codealmanac/app.py + note: Composition root wiring for the default scheduler adapter. + - id: launchd + type: file + path: src/codealmanac/integrations/automation/scheduler/launchd.py + note: macOS launchd scheduler adapter and launchctl subprocess calls. - id: setup-automation type: file path: src/codealmanac/services/setup/automation.py @@ -42,6 +50,12 @@ Use this guide to install and verify CodeAlmanac's local scheduled work. Setup c The usual successful state is simple: setup has selected a runner, scheduled the tasks you want, `automation status` reports them installed, and `sync status` or `jobs` can show local lifecycle activity. For background, see [Automation and update](../architecture/setup/automation-and-update), [Config keys](../reference/config-keys), and [Run queue and sync](../architecture/lifecycle/run-queue-and-sync). +## Check Platform Support + +Run setup on macOS. The README states that CodeAlmanac currently supports macOS with Codex or Claude Code [@readme]. The default application graph wires automation to `LaunchdSchedulerAdapter`, and that adapter shells out to `launchctl` when setup or config reconciliation installs, removes, or inspects scheduled jobs [@app] [@launchd]. + +If setup fails with a missing `launchctl` error, treat it as an unsupported-platform signal before debugging Claude, Codex, or runner readiness. Linux and Windows need a different scheduler adapter before local automation can be installed there [@app] [@launchd]. + ## Run Setup For the default unattended setup, run: From 6ddb3ec5771556abc3f7e4a07db3b6b41d21e3a6 Mon Sep 17 00:00:00 2001 From: divitsheth Date: Mon, 13 Jul 2026 21:08:29 -0700 Subject: [PATCH 10/21] almanac: strengthen wiki navigation --- almanac/architecture/wiki/README.md | 6 ++++++ almanac/getting-started.md | 6 ++++++ almanac/guides/add-a-harness-provider-adapter.md | 2 +- almanac/guides/debug-a-failed-lifecycle-run.md | 15 +++++++++++++++ almanac/guides/verify-a-wiki-change.md | 6 ++++++ 5 files changed, 34 insertions(+), 1 deletion(-) diff --git a/almanac/architecture/wiki/README.md b/almanac/architecture/wiki/README.md index 7909cf3c..47d4aca9 100644 --- a/almanac/architecture/wiki/README.md +++ b/almanac/architecture/wiki/README.md @@ -26,6 +26,10 @@ sources: type: file path: almanac/topics.yaml note: Topic graph entries for wiki, pages, sources, search, index, health, and topics. + - id: page-graph + type: wiki + path: concepts/page-graph + note: Concept page for pages, topics, links, backlinks, sources, and health as one wiki graph. --- # Wiki Architecture @@ -49,3 +53,5 @@ Finish with [Health and validation](health-and-validation) when changing graph c ## Neighboring Contracts The exact authored page format lives in [Frontmatter and sources](../../reference/page-format/frontmatter-and-sources) and [Links and routes](../../reference/page-format/links-and-routes). The broader concept is [Local repo wiki](../../concepts/local-repo-wiki), which explains why committed Markdown is the durable source while runtime databases are rebuildable local state. + +[Page graph](../../concepts/page-graph) is the concept page for the same neighborhood. It explains how pages, Markdown links, topics, backlinks, `sources:`, file references, and health checks form one graph rather than separate bookkeeping systems [@page-graph]. diff --git a/almanac/getting-started.md b/almanac/getting-started.md index fdd20437..38196c1d 100644 --- a/almanac/getting-started.md +++ b/almanac/getting-started.md @@ -14,6 +14,10 @@ sources: type: file path: docs/python-port-live-agreement.md note: Current Python rewrite agreement and active decisions. + - id: usefulness + type: wiki + path: concepts/wiki-usefulness-evaluation + note: Concept page for evaluating whether wiki changes help future agents complete work. --- # Getting Started @@ -45,6 +49,8 @@ Use the wiki as source-controlled product knowledge. Pages should preserve durab Before editing pages, read the relevant manual files under `src/codealmanac/manual/`. The writing manuals define leads, evidence, links, topics, and page-type shapes. After editing, run the repo's normal validation path for wiki changes; the public read surface includes `codealmanac health` and `codealmanac validate` [@repo-readme]. +For Garden work, also read [Wiki usefulness evaluation](concepts/wiki-usefulness-evaluation). It keeps validation, link health, and coverage in their proper role: diagnostics for whether the wiki helps future agents do real work, not the goal by themselves [@usefulness]. + ## Common Work Areas Use these routes when you already know the kind of work: diff --git a/almanac/guides/add-a-harness-provider-adapter.md b/almanac/guides/add-a-harness-provider-adapter.md index b16f6949..89a62a9e 100644 --- a/almanac/guides/add-a-harness-provider-adapter.md +++ b/almanac/guides/add-a-harness-provider-adapter.md @@ -1,6 +1,6 @@ --- title: Add A Harness Provider Adapter -topics: [guides, harnesses, yoke] +topics: [guides, harnesses, providers, yoke] sources: - id: pyproject type: file diff --git a/almanac/guides/debug-a-failed-lifecycle-run.md b/almanac/guides/debug-a-failed-lifecycle-run.md index 4fd3507e..d7feb79f 100644 --- a/almanac/guides/debug-a-failed-lifecycle-run.md +++ b/almanac/guides/debug-a-failed-lifecycle-run.md @@ -20,6 +20,15 @@ sources: - id: yoke-results type: file path: src/codealmanac/integrations/harnesses/yoke/results.py + - id: run-ledger + type: wiki + path: concepts/run-ledger + - id: run-states + type: wiki + path: reference/runs/run-states-and-events + - id: run-queue + type: wiki + path: architecture/lifecycle/run-queue-and-sync --- # Debug A Failed Lifecycle Run @@ -33,6 +42,12 @@ If the run is active, `codealmanac jobs attach ` follows the same event record until it becomes terminal. The readable log is the primary debugging surface; JSON output exposes the corresponding structured harness fields. +For background, [Run ledger](../concepts/run-ledger) explains why the record +survives the process, [Run states and events](../reference/runs/run-states-and-events) +defines the exact statuses and event kinds, and [Run queue and sync](../architecture/lifecycle/run-queue-and-sync) +explains how queued lifecycle work reaches the executor [@run-ledger] +[@run-states] [@run-queue]. + ## Identify The Boundary - Readiness or authentication failures appear before provider execution and diff --git a/almanac/guides/verify-a-wiki-change.md b/almanac/guides/verify-a-wiki-change.md index 9df352d5..b7cd07b6 100644 --- a/almanac/guides/verify-a-wiki-change.md +++ b/almanac/guides/verify-a-wiki-change.md @@ -14,6 +14,10 @@ sources: type: wiki page: architecture/wiki/health-and-validation note: Local architecture page explaining health and validation checks. + - id: usefulness + type: wiki + path: concepts/wiki-usefulness-evaluation + note: Concept page for evaluating wiki value by future-agent task outcomes. --- # Verify A Wiki Change @@ -22,6 +26,8 @@ Use this guide after editing wiki source under `almanac/`. A verified change has For the exact page metadata and citation contract, see [Frontmatter and sources](../reference/page-format/frontmatter-and-sources). For Markdown page-link rules, see [Links and routes](../reference/page-format/links-and-routes). +For Garden work, check [Wiki usefulness evaluation](../concepts/wiki-usefulness-evaluation) before polishing. A wiki change is useful when it helps future agents complete real repository work, while validation and link health are diagnostics for that goal [@usefulness]. + ## Steps Run `codealmanac validate` from the repository root. Validation checks source frontmatter shape, rejects runtime-state leaks, refreshes the index, and fails when graph or source-health issues remain [@health_service]. From b2f0e79657e9cd8a5e153adf4899bdbb9380b1c7 Mon Sep 17 00:00:00 2001 From: divitsheth Date: Tue, 14 Jul 2026 10:53:21 -0700 Subject: [PATCH 11/21] almanac: record product documentation evaluation signal --- .../concepts/wiki-usefulness-evaluation.md | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/almanac/concepts/wiki-usefulness-evaluation.md b/almanac/concepts/wiki-usefulness-evaluation.md index d24e59b6..7a13a9e2 100644 --- a/almanac/concepts/wiki-usefulness-evaluation.md +++ b/almanac/concepts/wiki-usefulness-evaluation.md @@ -6,6 +6,10 @@ sources: type: conversation path: /Users/divitsheth/.codex/sessions/2026/07/12/rollout-2026-07-12T17-29-11-019f58e0-bc84-7da3-a822-8e610a1935d8.jsonl note: Product discussion that framed useful wiki evaluation around agent task outcomes. + - id: product-doc-feedback + type: conversation + path: /Users/divitsheth/.codex/sessions/2026/07/13/rollout-2026-07-13T22-05-48-019f5f04-5aad-7060-827f-1dd293ed9794.jsonl + note: Customer-discovery notes that connected agent-oriented documentation to evaluation and benchmarking demand. - id: local-repo-wiki type: wiki path: concepts/local-repo-wiki @@ -60,3 +64,22 @@ Page-quality metrics remain valuable, but they are secondary. Accuracy against code, staleness, actionability, specificity, evidence quality, duplication, contradictions, link health, and coverage of important flows explain why the wiki helped or failed to help during task evaluation [@eval-discussion]. + +## Product Documentation Extension + +The same evaluation model is useful outside repo-owned codebase wikis, but it +changes the product question. Customer-discovery notes from Supabase and Autumn +Payments framed agent-oriented documentation as a real problem: agents can fail +to use a product as intended even when documentation exists [@product-doc-feedback]. + +That feedback pointed toward an evaluation framework before a new documentation +format. The desired system would score how well agents use a product from its +current docs, run tasks across agent sandboxes, identify documentation failures, +and then guide improvements [@product-doc-feedback]. In that setting, a wiki or +rewritten docs are an intervention. The durable signal is the measured agent +outcome, not the presence of another knowledge surface. + +This keeps benchmarking adjacent to wiki usefulness rather than separate from +it. A credible benchmark should prove that agents perform better with the +material they are given, whether that material is a CodeAlmanac repo wiki or +agent-facing product documentation [@eval-discussion] [@product-doc-feedback]. From 6027cdfc5a069a395d03b17154614b69bfa384b3 Mon Sep 17 00:00:00 2001 From: divitsheth Date: Tue, 14 Jul 2026 14:17:34 -0700 Subject: [PATCH 12/21] almanac: clarify hub reading paths --- almanac/README.md | 6 ++++ almanac/architecture/README.md | 31 ++++++++++++++++--- .../sources/source-resolution-and-runtime.md | 7 ++++- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/almanac/README.md b/almanac/README.md index 9157cb9e..b241be00 100644 --- a/almanac/README.md +++ b/almanac/README.md @@ -40,6 +40,12 @@ The wiki is organized by page role, not by source file: - [Decisions](decisions/) records constraints that shape future work. - [Reference](reference/) documents exact contracts, commands, formats, and state shapes. +Product boundary pages explain what the Python rewrite is and what it +intentionally leaves out. Start with [Local-only Python product](decisions/local-only-python-product) +and [Only Almanac root](decisions/only-almanac-root) before adding public +surface area, compatibility paths, hosted language, or release/demo framing +[@live-agreement]. + ## Reading Rule Use the wiki as maintained synthesis, then verify behavior against current code when the two disagree. The runtime kernel gives the same rule to writing agents: code is authoritative for behavior, Markdown links are the page-link syntax, and file evidence belongs in structured `sources:` entries [@kernel-prompt]. diff --git a/almanac/architecture/README.md b/almanac/architecture/README.md index c125772b..11053dfc 100644 --- a/almanac/architecture/README.md +++ b/almanac/architecture/README.md @@ -134,8 +134,29 @@ For authored wiki contracts, read [Page identity](wiki/page-identity), [Path nor ## Edges And Interfaces -Use [CLI adapter boundary](cli/adapter-boundary) and [Terminal output](cli/terminal-output) for command entrypoints and rendering [@cli-adapter] [@terminal-output]. Use [Harness contract](agent-runs/harness-contract) and [Provider adapters](agent-runs/provider-adapters) for Codex and Claude execution boundaries [@harness-contract] [@provider-adapters]. Use [Source resolution and runtime](sources/source-resolution-and-runtime) when changing ingest inputs or source adapters [@source-runtime]. - -[Agents and manuals](runtime-resources/prompts-and-manuals) covers the packaged Yoke agents and writing references used by lifecycle runs, and [Setup automation and update](setup/automation-and-update) covers setup-owned scheduler and update behavior [@agents-manuals] [@setup-automation]. - -[Local state](repositories/local-state), [Selection and root](repositories/selection-and-root), and [SQLite store boundaries](persistence/sqlite-store-boundaries) explain repository selection, runtime paths, and persistence ownership [@local-state] [@selection-root] [@sqlite-stores]. [Local viewer](viewer/local-viewer) explains the browser UI that projects the same wiki, topics, files, and jobs [@local-viewer]. +Use these routes when the change sits at a system edge: + +- Commands and output: [CLI adapter boundary](cli/adapter-boundary) explains + command entrypoints, and [Terminal output](cli/terminal-output) explains + human and JSON rendering [@cli-adapter] [@terminal-output]. +- Agent execution: [Harness contract](agent-runs/harness-contract) defines + the service-owned run interface, and [Yoke harness boundary](agent-runs/provider-adapters) + explains the current provider adapter [@harness-contract] + [@provider-adapters]. +- Source input: [Source resolution and runtime](sources/source-resolution-and-runtime) + owns ingest input resolution and source adapters. Pair it with [Source + material](../concepts/source-material) for the concept, [Source addresses](../reference/sources/source-addresses) + for accepted input strings, and [Frontmatter and sources](../reference/page-format/frontmatter-and-sources) + for page evidence [@source-runtime]. +- Packaged runtime resources: [Agents and manuals](runtime-resources/prompts-and-manuals) + covers the packaged Yoke agents and writing references used by lifecycle + runs [@agents-manuals]. +- Machine setup: [Setup automation and update](setup/automation-and-update) + covers setup-owned scheduler and update behavior [@setup-automation]. +- Repository and storage state: [Local state](repositories/local-state), + [Selection and root](repositories/selection-and-root), and [SQLite store + boundaries](persistence/sqlite-store-boundaries) explain repository + selection, runtime paths, and persistence ownership [@local-state] + [@selection-root] [@sqlite-stores]. +- Browser projection: [Local viewer](viewer/local-viewer) explains the browser + UI that projects the same wiki, topics, files, and jobs [@local-viewer]. diff --git a/almanac/architecture/sources/source-resolution-and-runtime.md b/almanac/architecture/sources/source-resolution-and-runtime.md index 39808b5a..451b52a5 100644 --- a/almanac/architecture/sources/source-resolution-and-runtime.md +++ b/almanac/architecture/sources/source-resolution-and-runtime.md @@ -62,4 +62,9 @@ Sync does not ingest every discovered transcript. It matches each transcript `cw ## Related Reference -Accepted input forms are summarized in [Source Addresses](../../reference/sources/source-addresses). Page evidence uses a different contract, [Frontmatter And Sources](../../reference/page-format/frontmatter-and-sources). +For source work, read [Source Material](../../concepts/source-material) first +to keep ingest input separate from page evidence. Then use this page for the +service boundary, [Source Addresses](../../reference/sources/source-addresses) +for accepted input strings, [Frontmatter And Sources](../../reference/page-format/frontmatter-and-sources) +for page evidence, and [Path Normalization And File Refs](../wiki/path-normalization-and-file-refs) +for file-reference matching. From 09cde50141be703016c69e154629a4a5613f6048 Mon Sep 17 00:00:00 2001 From: divitsheth Date: Tue, 14 Jul 2026 20:44:28 -0700 Subject: [PATCH 13/21] almanac: improve yoke and product routing --- almanac/README.md | 6 ++++++ almanac/architecture/README.md | 9 ++++++--- .../agent-runs/provider-adapters.md | 9 ++++++++- almanac/architecture/lifecycle/README.md | 19 ++++++++++++++++++- almanac/architecture/lifecycle/workflows.md | 2 +- almanac/decisions/no-page-kind-field.md | 6 ++++-- .../demo-codealmanac-in-launch-video.md | 7 +++++++ almanac/reference/config-keys.md | 3 +++ almanac/topics.yaml | 2 +- 9 files changed, 54 insertions(+), 9 deletions(-) diff --git a/almanac/README.md b/almanac/README.md index b241be00..4bdb6cf6 100644 --- a/almanac/README.md +++ b/almanac/README.md @@ -46,6 +46,12 @@ and [Only Almanac root](decisions/only-almanac-root) before adding public surface area, compatibility paths, hosted language, or release/demo framing [@live-agreement]. +For product work, [Wiki usefulness evaluation](concepts/wiki-usefulness-evaluation) +defines what makes a wiki change worth preserving, [Demo CodeAlmanac in a +launch video](guides/demo-codealmanac-in-launch-video) keeps demo framing tied +to the local product, and [Release package](guides/release-package) covers the +public Python package surface [@repo-readme] [@live-agreement]. + ## Reading Rule Use the wiki as maintained synthesis, then verify behavior against current code when the two disagree. The runtime kernel gives the same rule to writing agents: code is authoritative for behavior, Markdown links are the page-link syntax, and file evidence belongs in structured `sources:` entries [@kernel-prompt]. diff --git a/almanac/architecture/README.md b/almanac/architecture/README.md index 11053dfc..9fcf9d4d 100644 --- a/almanac/architecture/README.md +++ b/almanac/architecture/README.md @@ -141,8 +141,9 @@ Use these routes when the change sits at a system edge: human and JSON rendering [@cli-adapter] [@terminal-output]. - Agent execution: [Harness contract](agent-runs/harness-contract) defines the service-owned run interface, and [Yoke harness boundary](agent-runs/provider-adapters) - explains the current provider adapter [@harness-contract] - [@provider-adapters]. + explains the current Yoke provider adapter, including Codex and Claude run + options, readiness checks, runtime cache placement, and event projection + [@harness-contract] [@provider-adapters]. - Source input: [Source resolution and runtime](sources/source-resolution-and-runtime) owns ingest input resolution and source adapters. Pair it with [Source material](../concepts/source-material) for the concept, [Source addresses](../reference/sources/source-addresses) @@ -150,7 +151,9 @@ Use these routes when the change sits at a system edge: for page evidence [@source-runtime]. - Packaged runtime resources: [Agents and manuals](runtime-resources/prompts-and-manuals) covers the packaged Yoke agents and writing references used by lifecycle - runs [@agents-manuals]. + runs. Use this page for agent instruction packaging; use [Yoke harness + boundary](agent-runs/provider-adapters) for provider execution behavior + [@agents-manuals] [@provider-adapters]. - Machine setup: [Setup automation and update](setup/automation-and-update) covers setup-owned scheduler and update behavior [@setup-automation]. - Repository and storage state: [Local state](repositories/local-state), diff --git a/almanac/architecture/agent-runs/provider-adapters.md b/almanac/architecture/agent-runs/provider-adapters.md index f1ddfa08..cb976a31 100644 --- a/almanac/architecture/agent-runs/provider-adapters.md +++ b/almanac/architecture/agent-runs/provider-adapters.md @@ -50,7 +50,14 @@ models [@adapter] [@contract]. The adapter explicitly selects Codex app-server and leaves Claude on Yoke's default Claude surface. It loads the requested build, ingest, or garden agent from the packaged Yoke collection, forwards the task prompt unchanged, and -applies the trusted non-interactive permission and timeout policy [@adapter]. +applies the provider-specific non-interactive run policy [@adapter]. + +Codex runs use the ephemeral app-server surface, danger-full-access sandbox, +approval mode `never`, and provider network access disabled [@adapter] +[@tests]. Claude runs use the fixed allowed tool set, permission mode +`dontAsk`, no Claude settings sources, strict MCP config, and an empty MCP +server map [@adapter] [@tests]. Both providers receive explicit run timeouts: +30 minutes for Codex and 90 minutes for Claude [@adapter]. ## Runtime Root diff --git a/almanac/architecture/lifecycle/README.md b/almanac/architecture/lifecycle/README.md index 33dce9a5..af8ccc19 100644 --- a/almanac/architecture/lifecycle/README.md +++ b/almanac/architecture/lifecycle/README.md @@ -34,6 +34,14 @@ sources: type: wiki path: architecture/runtime-resources/prompts-and-manuals note: Architecture page for packaged Yoke agents and writing manuals used by lifecycle operations. + - id: harness-contract + type: wiki + path: architecture/agent-runs/harness-contract + note: Architecture page for the normalized harness execution contract. + - id: provider-adapters + type: wiki + path: architecture/agent-runs/provider-adapters + note: Architecture page for Yoke provider execution behavior. --- # Lifecycle @@ -54,4 +62,13 @@ Use [Mutation safety](mutation-safety) when changing allowed files, auto-commit ## Neighboring Pages -[Run states and events](../../reference/runs/run-states-and-events) is the exact reference for run kinds, statuses, queued specs, cancellation, attach, and logs [@run-states]. [Lifecycle operation](../../concepts/lifecycle-operation) is the concept page for the page-writing operation family [@lifecycle-concept]. [Agents and manuals](../runtime-resources/prompts-and-manuals) explains the packaged Yoke agents and writing manuals that lifecycle workflows bind into page-writing runs [@agents-manuals]. +[Run states and events](../../reference/runs/run-states-and-events) is the +exact reference for run kinds, statuses, queued specs, cancellation, attach, +and logs [@run-states]. [Lifecycle operation](../../concepts/lifecycle-operation) +is the concept page for the page-writing operation family [@lifecycle-concept]. +[Agents and manuals](../runtime-resources/prompts-and-manuals) explains the +packaged Yoke agents and writing manuals that lifecycle workflows bind into +page-writing runs [@agents-manuals]. [Harness contract](../agent-runs/harness-contract) +and [Yoke harness boundary](../agent-runs/provider-adapters) explain the +execution boundary after a workflow has prepared its prompt [@harness-contract] +[@provider-adapters]. diff --git a/almanac/architecture/lifecycle/workflows.md b/almanac/architecture/lifecycle/workflows.md index fe11aa3c..e4b40b42 100644 --- a/almanac/architecture/lifecycle/workflows.md +++ b/almanac/architecture/lifecycle/workflows.md @@ -46,7 +46,7 @@ The source runtime layer is important because ingest should give the agent concr Garden is the maintenance workflow for an existing wiki. Before calling the operation runner, it reads the current index summary and health report, records that it prepared garden context, and renders a prompt with the current wiki state [@garden-workflow]. -Garden does not resolve external source material. Its job is to improve structure and quality from the wiki's own graph: weak pages, stale health findings, missing links, weak topics, and similar maintenance work. +Garden does not resolve external source material. Its job is to improve structure and quality from the wiki's own graph: weak pages, stale health findings, missing links, weak topics, and similar maintenance work [@garden-workflow]. ## Sync Is Not An Operation diff --git a/almanac/decisions/no-page-kind-field.md b/almanac/decisions/no-page-kind-field.md index 14bc7bfb..791ea8bf 100644 --- a/almanac/decisions/no-page-kind-field.md +++ b/almanac/decisions/no-page-kind-field.md @@ -34,7 +34,8 @@ it. ## Status Accepted (deferred). No `kind` field exists today. Revisit only when a concrete -reader workflow needs kind-specific behavior. +reader workflow needs kind-specific behavior [@frontmatter-parser] +[@frontmatter-reference]. ## Context @@ -48,7 +49,8 @@ field [@frontmatter-reference]. Page type is currently expressed only through folder placement (`concepts/`, `architecture/`, `guides/`, `decisions/`, `reference/`) and the matching manual page. That is enough for a human or agent writer to follow the -right shape, but it is not machine-checked. +right shape, but it is not machine-checked [@manual-overview] +[@frontmatter-reference]. ## Decision diff --git a/almanac/guides/demo-codealmanac-in-launch-video.md b/almanac/guides/demo-codealmanac-in-launch-video.md index 4cd9d4f4..cd89e1fe 100644 --- a/almanac/guides/demo-codealmanac-in-launch-video.md +++ b/almanac/guides/demo-codealmanac-in-launch-video.md @@ -96,3 +96,10 @@ account, telemetry, analytics, or usage tracking; user code, transcripts, and wiki content stay local except for the selected model provider used by the user's own Codex or Claude account during lifecycle runs [@public-readme] [@live-agreement]. + +## Related Pages + +See [Local viewer](../architecture/viewer/local-viewer), +[CLI public command surface](../reference/cli/public-command-surface), +[Local-only Python product](../decisions/local-only-python-product), and +[Wiki usefulness evaluation](../concepts/wiki-usefulness-evaluation). diff --git a/almanac/reference/config-keys.md b/almanac/reference/config-keys.md index 4539f777..5f349685 100644 --- a/almanac/reference/config-keys.md +++ b/almanac/reference/config-keys.md @@ -54,6 +54,9 @@ written [@config-tests]. ## Supported Keys +The supported keys and built-in defaults come from the typed config model and +the public config parser [@config-models] [@config-parser]. + | Key | Type | Default | Valid values | | --- | --- | --- | --- | | `auto_commit` | Boolean | `true` | `true` or `false` | diff --git a/almanac/topics.yaml b/almanac/topics.yaml index 8c0eaa49..e52475e5 100644 --- a/almanac/topics.yaml +++ b/almanac/topics.yaml @@ -105,7 +105,7 @@ topics: parents: [architecture] - slug: runtime-resources title: Runtime Resources - description: Packaged prompts, manuals, and operation prompt rendering + description: Packaged Yoke agents, agent instructions, and writing manuals parents: [architecture] - slug: prompts title: Prompts From 0d2c84737b09ef1fbeb842040893207a5801ce43 Mon Sep 17 00:00:00 2001 From: divitsheth Date: Tue, 14 Jul 2026 20:55:27 -0700 Subject: [PATCH 14/21] almanac: record setup and launch learnings --- .../setup/automation-and-update.md | 6 ++++++ .../guides/demo-codealmanac-in-launch-video.md | 18 ++++++++++++++++++ almanac/guides/setup-local-automation.md | 2 ++ 3 files changed, 26 insertions(+) diff --git a/almanac/architecture/setup/automation-and-update.md b/almanac/architecture/setup/automation-and-update.md index 06394d2e..699fdded 100644 --- a/almanac/architecture/setup/automation-and-update.md +++ b/almanac/architecture/setup/automation-and-update.md @@ -18,6 +18,10 @@ sources: type: file path: src/codealmanac/services/setup/automation.py note: Setup-side automation task selection. + - id: config_service + type: file + path: src/codealmanac/services/config/service.py + note: User config writes and automation reconciliation. - id: automation_service type: file path: src/codealmanac/services/automation/service.py @@ -80,6 +84,8 @@ The macOS implementation writes launchd plists under `~/Library/LaunchAgents`, c The default application wiring is launchd-backed. `create_services` constructs `AutomationService` with `LaunchdSchedulerAdapter`, then injects it into the config service. The adapter shells out to `launchctl` for install, uninstall, and status checks [@app][@launchd]. Config reconciliation is macOS-specific until another scheduler adapter is wired. There is no platform-selection branch in the composition root, so setup on a machine without `launchctl` reaches the launchd adapter and surfaces a scheduler execution failure instead of selecting a Linux or Windows scheduler [@app][@launchd]. +That unsupported-platform failure is not atomic. `SetupService.run` writes user config before instruction installation, `ConfigService.update` persists the TOML values before reconciling automation, and `LaunchdSchedulerAdapter.install` writes the plist and log directories before it calls `launchctl` [@setup_service][@config_service][@launchd]. A Linux or Windows setup attempt can therefore leave `~/.codealmanac/config.toml`, installed instruction files, or `~/Library/LaunchAgents/com.codealmanac..plist` artifacts behind even though scheduled automation did not install successfully. + ## Update Safety Manual update and scheduled update share the same planning logic. `plan_update` refuses editable installs, maps uv installs to `uv tool upgrade codealmanac`, maps pip installs to `python -m pip install --upgrade codealmanac`, and refuses unknown installers with a suggested manual command [@updates]. diff --git a/almanac/guides/demo-codealmanac-in-launch-video.md b/almanac/guides/demo-codealmanac-in-launch-video.md index cd89e1fe..a8aac588 100644 --- a/almanac/guides/demo-codealmanac-in-launch-video.md +++ b/almanac/guides/demo-codealmanac-in-launch-video.md @@ -26,6 +26,10 @@ sources: type: web url: https://news.ycombinator.com/item?id=48849361 note: Initial Show HN post for CodeAlmanac. + - id: hn-advice + type: web + url: https://news.ycombinator.com/item?id=22336638 + note: Hacker News moderator advice on Show HN copy, backstory, proof, and avoiding marketing language. --- # Demo CodeAlmanac In A Launch Video @@ -88,6 +92,20 @@ had an initial Show HN on July 9, 2026 [@show-hn]. The later Launch HN should be framed as a fuller introduction to the same local, open-source CLI rather than as a major product-change announcement [@public-readme] [@live-agreement]. +For HN specifically, lead with evidence before philosophy. The copy should open +with a concrete coding-agent failure, show the generated wiki page or query that +would have prevented it, and then name the product. HN's own advice asks Show HN +authors to explain the backstory, state clearly what the project does, make it +easy to try, and remove marketing language [@hn-advice]. For CodeAlmanac, the +minimum proof is one real page, one `codealmanac search` or `show` retrieval, +and one comparison against the existing alternative of putting more context in +`CLAUDE.md` or ordinary docs [@public-readme] [@differentiation]. + +The final HN submission text should be written by the maintainer, not generated +or polished by an agent. Agents can prepare factual notes, examples, and a proof +checklist, but HN's moderator guidance warns that LLM-shaped launch copy creates +backlash on HN [@hn-advice]. + The concise answer for a missing demo video is that HN users can install and try the CLI directly without creating an account [@public-readme] [@live-agreement]. diff --git a/almanac/guides/setup-local-automation.md b/almanac/guides/setup-local-automation.md index 7c2cc114..6e0c1597 100644 --- a/almanac/guides/setup-local-automation.md +++ b/almanac/guides/setup-local-automation.md @@ -56,6 +56,8 @@ Run setup on macOS. The README states that CodeAlmanac currently supports macOS If setup fails with a missing `launchctl` error, treat it as an unsupported-platform signal before debugging Claude, Codex, or runner readiness. Linux and Windows need a different scheduler adapter before local automation can be installed there [@app] [@launchd]. +Check for partial local state after that failure. Setup writes config before installing instructions, and the launchd adapter writes plist and log paths before it shells out to `launchctl` [@setup-service] [@launchd]. On a non-macOS machine, remove or ignore those local artifacts before rerunning setup after a platform-support fix. + ## Run Setup For the default unattended setup, run: From 6dfdf6a9e8e1397d038f564ea7d8f12eefb888a3 Mon Sep 17 00:00:00 2001 From: divitsheth Date: Wed, 15 Jul 2026 14:10:25 -0700 Subject: [PATCH 15/21] almanac: add architecture routing hubs --- almanac/architecture/README.md | 26 +++++-- almanac/architecture/agent-runs/README.md | 83 +++++++++++++++++++++++ almanac/architecture/setup/README.md | 71 +++++++++++++++++++ 3 files changed, 173 insertions(+), 7 deletions(-) create mode 100644 almanac/architecture/agent-runs/README.md create mode 100644 almanac/architecture/setup/README.md diff --git a/almanac/architecture/README.md b/almanac/architecture/README.md index 9fcf9d4d..72462ebf 100644 --- a/almanac/architecture/README.md +++ b/almanac/architecture/README.md @@ -66,6 +66,10 @@ sources: type: wiki path: architecture/agent-runs/harness-contract note: Architecture page for normalized harness execution. + - id: agent-runs-hub + type: wiki + path: architecture/agent-runs + note: Architecture hub for harness contracts, Yoke provider execution, events, and model choices. - id: provider-adapters type: wiki path: architecture/agent-runs/provider-adapters @@ -102,6 +106,10 @@ sources: type: wiki path: architecture/setup/automation-and-update note: Architecture page for setup-owned automation and update behavior. + - id: setup-hub + type: wiki + path: architecture/setup + note: Architecture hub for setup, instruction installation, automation, config, and local state. --- # Architecture @@ -139,11 +147,13 @@ Use these routes when the change sits at a system edge: - Commands and output: [CLI adapter boundary](cli/adapter-boundary) explains command entrypoints, and [Terminal output](cli/terminal-output) explains human and JSON rendering [@cli-adapter] [@terminal-output]. -- Agent execution: [Harness contract](agent-runs/harness-contract) defines - the service-owned run interface, and [Yoke harness boundary](agent-runs/provider-adapters) - explains the current Yoke provider adapter, including Codex and Claude run - options, readiness checks, runtime cache placement, and event projection - [@harness-contract] [@provider-adapters]. +- Agent execution: [Agent runs](agent-runs/) is the hub for the service-owned + harness contract, the current Yoke provider adapter, event shape, and model + catalog choices. Use [Harness contract](agent-runs/harness-contract) for the + normalized run interface and [Yoke harness boundary](agent-runs/provider-adapters) + for Codex and Claude run options, readiness checks, runtime cache placement, + and event projection [@agent-runs-hub] [@harness-contract] + [@provider-adapters]. - Source input: [Source resolution and runtime](sources/source-resolution-and-runtime) owns ingest input resolution and source adapters. Pair it with [Source material](../concepts/source-material) for the concept, [Source addresses](../reference/sources/source-addresses) @@ -154,8 +164,10 @@ Use these routes when the change sits at a system edge: runs. Use this page for agent instruction packaging; use [Yoke harness boundary](agent-runs/provider-adapters) for provider execution behavior [@agents-manuals] [@provider-adapters]. -- Machine setup: [Setup automation and update](setup/automation-and-update) - covers setup-owned scheduler and update behavior [@setup-automation]. +- Machine setup: [Setup](setup/) is the hub for instruction installation, + automation, config, update, and local setup state. Use [Setup automation and update](setup/automation-and-update) + for setup-owned scheduler and update behavior [@setup-hub] + [@setup-automation]. - Repository and storage state: [Local state](repositories/local-state), [Selection and root](repositories/selection-and-root), and [SQLite store boundaries](persistence/sqlite-store-boundaries) explain repository diff --git a/almanac/architecture/agent-runs/README.md b/almanac/architecture/agent-runs/README.md new file mode 100644 index 00000000..7b5bb936 --- /dev/null +++ b/almanac/architecture/agent-runs/README.md @@ -0,0 +1,83 @@ +--- +title: Agent Runs +topics: [architecture, agent-runs, harnesses, providers, yoke, overview] +sources: + - id: topics + type: file + path: almanac/topics.yaml + note: Topic graph entries for agent runs, harnesses, providers, and Yoke. + - id: harness-contract + type: wiki + path: architecture/agent-runs/harness-contract + note: Architecture page for the service-owned harness contract. + - id: yoke-boundary + type: wiki + path: architecture/agent-runs/provider-adapters + note: Architecture page for the current Yoke provider adapter boundary. + - id: agents-manuals + type: wiki + path: architecture/runtime-resources/prompts-and-manuals + note: Architecture page for packaged lifecycle agents and manuals. + - id: event-shape + type: wiki + path: reference/harness-event-shape + note: Reference page for normalized harness event fields. + - id: model-catalog + type: wiki + path: decisions/controlled-model-catalog + note: Decision page for supported runner/model ownership. + - id: adapter-guide + type: wiki + path: guides/add-a-harness-provider-adapter + note: Guide for adding a new runner or changing a Yoke surface. +--- + +# Agent Runs + +Agent runs are the architecture neighborhood for executing CodeAlmanac +lifecycle agents through local AI harnesses. The `agent-runs` topic groups the +service-owned harness contract, provider adapter boundary, event reference, and +provider-change guide, while narrower `harnesses`, `providers`, and `yoke` +topics keep those pages retrievable from their specific concerns [@topics]. +Read this hub when changing how build, ingest, or garden crosses from +CodeAlmanac workflows into a local agent provider. + +The key boundary is that workflows send one normalized request and receive one +normalized result. Provider details stay behind the harness adapter, while +runtime instructions and manuals stay in the packaged agent-resource area +[@harness-contract] [@yoke-boundary] [@agents-manuals]. + +## Reading Order + +Start with [Harness contract](harness-contract). It defines +`RunHarnessRequest`, `HarnessRunResult`, readiness checks, transcript +references, and the provider-neutral event stream that lifecycle workflows and +job views consume [@harness-contract]. + +Then read [Yoke harness boundary](provider-adapters). It explains the current +provider integration: `YokeHarnessAdapter` loads the packaged build, ingest, or +garden agent, selects the Claude or Codex Yoke surface, applies CodeAlmanac's +run options, projects live provider events, and keeps Yoke runtime caches under +local CodeAlmanac state [@yoke-boundary]. + +Use [Agents and manuals](../runtime-resources/prompts-and-manuals) when the +change concerns the instructions or manual material a lifecycle agent receives. +That page owns packaged Yoke agent identities and writing references, not the +provider execution mechanics [@agents-manuals]. + +Use [Harness event shape](../../reference/harness-event-shape) when changing +the durable event vocabulary for logs, attach streams, and viewer displays +[@event-shape]. Use [Controlled model catalog](../../decisions/controlled-model-catalog) +when changing supported runner/model pairs or setup defaults [@model-catalog]. + +## Change Path + +Provider support normally starts in Yoke. CodeAlmanac should add a new +`HarnessKind`, model catalog entries, registration, and boundary tests only +after the provider or surface exists in Yoke [@adapter-guide]. + +For CodeAlmanac-side work, follow [Add a harness provider adapter](../../guides/add-a-harness-provider-adapter). +The guide keeps provider protocol work out of this repository and focuses this +codebase on product-owned choices: which local runner exists, which models are +accepted, which Yoke surface is selected, and which normalized events become +durable product facts [@adapter-guide]. diff --git a/almanac/architecture/setup/README.md b/almanac/architecture/setup/README.md new file mode 100644 index 00000000..5323ea09 --- /dev/null +++ b/almanac/architecture/setup/README.md @@ -0,0 +1,71 @@ +--- +title: Setup +topics: [architecture, setup, automation, config, overview] +sources: + - id: topics + type: file + path: almanac/topics.yaml + note: Topic graph entries for setup, automation, config, and local state. + - id: automation-update + type: wiki + path: architecture/setup/automation-and-update + note: Architecture page for setup, scheduled automation, update, and uninstall. + - id: instruction-installation + type: wiki + path: architecture/setup/instruction-installation + note: Architecture page for installing CodeAlmanac guidance into Claude and Codex. + - id: setup-guide + type: wiki + path: guides/setup-local-automation + note: Operational guide for installing, verifying, and changing local automation. + - id: config-keys + type: wiki + path: reference/config-keys + note: Reference page for user config keys, harness defaults, and automation policy. + - id: local-state + type: wiki + path: reference/local-state-layout + note: Reference page for local runtime paths touched by setup and automation. +--- + +# Setup + +Setup is the architecture neighborhood for machine-level CodeAlmanac state: +installed agent instructions, user config, scheduled local automation, package +updates, and uninstall behavior. The setup topic sits near automation and +config because `codealmanac setup` writes user policy and then reconciles local +scheduler state; it is not a repository wiki-writing operation [@topics] +[@automation-update] [@config-keys]. + +Read this hub when changing setup, uninstall, instruction installation, +automation reconciliation, or update scheduling. For task-oriented recovery and +verification, use the setup guide rather than copying operational steps into +architecture pages [@setup-guide]. + +## Reading Order + +Start with [Setup automation and update](automation-and-update). It explains +the machine-level maintenance layer: setup writes config, installs selected +instruction targets, reconciles sync, Garden, and update jobs through launchd, +and removes CodeAlmanac-owned local artifacts during uninstall +[@automation-update]. + +Then read [Instruction installation](instruction-installation) when the change +touches Claude or Codex global instructions. That page owns the per-target file +mechanics and the installed guide text. It is separate from scheduled +automation because instruction files live in the user's agent config, while +automation jobs live under scheduler state [@instruction-installation]. + +Use [Config keys](../../reference/config-keys) for exact user TOML keys, +defaults, controlled harness models, and automation policy fields +[@config-keys]. Use [Local state layout](../../reference/local-state-layout) +when the change touches `~/.codealmanac/`, launchd logs, or other runtime +paths that setup and automation create [@local-state]. + +## Operator Route + +[Setup local automation](../../guides/setup-local-automation) is the operator +path. It covers macOS support, missing-`launchctl` failures, setup flags, +direct config changes, `automation status`, and uninstall commands +[@setup-guide]. Keep platform recovery and verification steps there; keep +architecture pages focused on ownership, boundaries, and state consequences. From 2423b1e9506e4ce0a6802f5e4f3759502be96541 Mon Sep 17 00:00:00 2001 From: divitsheth Date: Wed, 15 Jul 2026 15:03:49 -0700 Subject: [PATCH 16/21] almanac: document direct-url update gap --- almanac/architecture/setup/automation-and-update.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/almanac/architecture/setup/automation-and-update.md b/almanac/architecture/setup/automation-and-update.md index 699fdded..04ff09ca 100644 --- a/almanac/architecture/setup/automation-and-update.md +++ b/almanac/architecture/setup/automation-and-update.md @@ -96,7 +96,9 @@ The current update lock is a PID-file lease. `UpdateLockStore.acquire` writes a If the lock is replaced with FileLock or another file-locking library, the release path should let the library own the lock file instead of deleting it after release. The reviewed FileLock replacement showed why: a process can acquire after the release call and before the manual deletion, then another process can create a new lock file while the acquired process still holds the old file descriptor [@filelock_review]. Tests for that shape should assert that another process can acquire after release, not that the lock file disappears; once timestamp staleness is gone, `now`, `stale_after`, and `lock_stale_after` should be removed from the update path instead of kept as unused request plumbing [@filelock_review][@setup_requests]. -The editable-install guard does not cover every PEP 610 direct-url install. The metadata reader records `source_url` from `direct_url.json`, but `update_method` only uses the `editable` flag before falling through to the installer-based uv or pip plan [@update_metadata][@updates]. A non-editable local path, VCS, or direct archive install with `INSTALLER` set to `uv` or `pip` can therefore still be upgraded through the normal package command. +The editable-install guard does not cover every PEP 610 direct-url install. The metadata reader records `source_url` from `direct_url.json`, but `update_method` only uses the `editable` flag before falling through to the installer-based uv or pip plan [@update_metadata][@updates]. The reader also collapses PEP 610 shape down to `editable` and `source_url`; it does not preserve whether the direct URL came from `dir_info`, `vcs_info`, or `archive_info` [@update_metadata]. A non-editable local path, VCS, or direct archive install with `INSTALLER` set to `uv` or `pip` can therefore still be upgraded through the normal package command. + +Tests pin the editable-install refusal, scheduled editable skip, uv plan, and pip plan, but they do not exercise `read_direct_url` directly or prove that a pip install with `source_url` is refused [@update_tests]. Future work that broadens source-install protection should add those cases before changing `update_method`, then decide whether non-editable local directories, VCS URLs, and archives share one unsupported path or need different repair guidance. This shape matches the active agreement: scheduled auto-update is an explicit local automation task, not a sync or Garden side effect. The agreement also states that scheduled update should skip editable installs, skip active lifecycle jobs, use a global lock, support uv tool and pip installs, and run the same two smoke checks [@live_agreement]. From 18d81de5bc1b6d2038fee8d46c512ef9518d5bec Mon Sep 17 00:00:00 2001 From: divitsheth Date: Fri, 10 Jul 2026 12:14:25 -0700 Subject: [PATCH 17/21] almanac: connect release and topic guide pages --- almanac/architecture/wiki/topics-dag.md | 4 +++- almanac/guides/release-package.md | 4 ++-- almanac/guides/verify-a-wiki-change.md | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/almanac/architecture/wiki/topics-dag.md b/almanac/architecture/wiki/topics-dag.md index ca9994cc..0ce70db1 100644 --- a/almanac/architecture/wiki/topics-dag.md +++ b/almanac/architecture/wiki/topics-dag.md @@ -30,7 +30,7 @@ sources: # Topics DAG -The topics DAG is the browseable topic graph for a repo wiki. It is built from `almanac/topics.yaml` plus page `topics:` frontmatter, and it gives pages a subject map that is separate from the folder tree. The graph is a directed acyclic graph: a topic may have parents, but parent links cannot form a cycle [@topic-graph]. +The topics DAG is the browseable topic graph for a repo wiki. It is built from `almanac/topics.yaml` plus page `topics:` frontmatter, and it gives pages a subject map that is separate from the folder tree. The graph is a directed acyclic graph: a topic may have parents, but parent links cannot form a cycle [@topic-graph]. The exact YAML shape is documented in [Topics YAML](../../reference/topics-yaml), and maintainer steps live in [Maintain topics](../../guides/maintain-topics). This area is split into read and write responsibilities. `TopicsService` is the service-facing facade for list, show, create, describe, link, unlink, rename, and delete [@topics-service]. The mutation executor owns file writes, page frontmatter rewrites, graph checks, and index refresh after topic changes [@topic-mutations]. That split keeps topic commands deterministic while the derived index remains the read model. @@ -65,3 +65,5 @@ The live agreement makes this split explicit: topic read orchestration, graph me When changing this area, keep that boundary intact. Reads should stay index-backed. Mutations should update authored Markdown/YAML, refresh the index, and reject graph shapes that would make topic browsing ambiguous. For task steps, use [Maintain topics](../../guides/maintain-topics). For the exact `topics.yaml` schema and mutation contract, use [Topics YAML](../../reference/topics-yaml). + +After changing topic source, verify the graph with [Verify a wiki change](../../guides/verify-a-wiki-change). diff --git a/almanac/guides/release-package.md b/almanac/guides/release-package.md index 969f51ab..77aa8608 100644 --- a/almanac/guides/release-package.md +++ b/almanac/guides/release-package.md @@ -30,11 +30,11 @@ sources: # Release Package -Use this guide when publishing the `codealmanac` Python package to PyPI. A release publishes the local CLI package and its packaged resources; it does not publish a hosted service, npm package, SDK, MCP package, or legacy command alias, matching the [Local-only Python product](../decisions/local-only-python-product) decision [@release-doc] [@public-contract-tests]. The release is not done when PyPI accepts files. It is done when clean installed artifacts and the public install path can run the `codealmanac` command outside the repo developer environment [@release-doc] [@readme]. +Use this guide when publishing the `codealmanac` Python package to PyPI. A release publishes the local CLI package and its packaged resources; it follows the [Local-only Python product](../decisions/local-only-python-product) decision and does not publish a hosted service, npm package, SDK, MCP package, or legacy command alias [@release-doc] [@public-contract-tests]. The release is not done when PyPI accepts files. It is done when clean installed artifacts and the public install path can run the `codealmanac` command outside the repo developer environment [@release-doc] [@readme]. ## Preconditions -Start from a clean checkout of the release branch. `pyproject.toml` owns the package version, requires Python 3.12 or newer, and exposes exactly one console script: `codealmanac = "codealmanac.cli.main:main"` [@pyproject]. The release document states that stable releases publish from `main` to the normal PyPI release channel and that version numbers must not be reused [@release-doc]. +Start from a clean checkout of the release branch. `pyproject.toml` owns the package version, requires Python 3.12 or newer, and exposes exactly one console script: `codealmanac = "codealmanac.cli.main:main"` [@pyproject]. The [public command surface](../reference/cli/public-command-surface) is the contract that release smoke should prove from installed artifacts. The release document states that stable releases publish from `main` to the normal PyPI release channel and that version numbers must not be reused [@release-doc]. Keep the package surface narrow. Public-contract tests reject npm release language, old install surfaces, hosted commands, legacy aliases, and public SDK or MCP modules [@public-contract-tests]. If those tests fail, fix the public contract before publishing. diff --git a/almanac/guides/verify-a-wiki-change.md b/almanac/guides/verify-a-wiki-change.md index b7cd07b6..ffe1581e 100644 --- a/almanac/guides/verify-a-wiki-change.md +++ b/almanac/guides/verify-a-wiki-change.md @@ -22,7 +22,7 @@ sources: # Verify A Wiki Change -Use this guide after editing wiki source under `almanac/`. A verified change has valid page links, usable source citations, no runtime-state files in the wiki tree, and a refreshed index that can represent the current Markdown [@health_service]. +Use this guide after editing wiki source under `almanac/`. A verified change has valid page links, usable source citations, no runtime-state files in the wiki tree, and a refreshed index that can represent the current Markdown [@health_service]. The checks here enforce the page-format rules described by [Frontmatter and sources](../reference/page-format/frontmatter-and-sources), [Links and routes](../reference/page-format/links-and-routes), and [Health and validation](../architecture/wiki/health-and-validation). For the exact page metadata and citation contract, see [Frontmatter and sources](../reference/page-format/frontmatter-and-sources). For Markdown page-link rules, see [Links and routes](../reference/page-format/links-and-routes). @@ -34,7 +34,7 @@ Run `codealmanac validate` from the repository root. Validation checks source fr If validation fails, fix the reported wiki source issue rather than editing runtime state. Broken page links need a real target page or plain text. Missing citations need a matching `sources:` entry or a removed citation marker. Unused sources should be cited near the claim they support or removed. See [Health and validation](../architecture/wiki/health-and-validation) for what each check looks for and why [@health_page]. -Use `codealmanac health` when you want the same graph report without treating it as a pass/fail gate. Use `codealmanac search`, `codealmanac show`, and `codealmanac topics` to spot-check that the page can be found and read through the public read surface [@repo_readme]. +Use `codealmanac health` when you want the same graph report without treating it as a pass/fail gate. Use `codealmanac search`, `codealmanac show`, and `codealmanac topics` to spot-check that the page can be found and read through the public read surface [@repo_readme]. When a topic change is part of the edit, use [Maintain topics](maintain-topics) before treating validation as the whole review. ## Recovery From a5d4b6023039d4367c9a195744347fa5448da218 Mon Sep 17 00:00:00 2001 From: divitsheth Date: Fri, 10 Jul 2026 13:20:34 -0700 Subject: [PATCH 18/21] almanac: clarify setup and transcript boundaries --- .../setup/automation-and-update.md | 16 ++++++++++ .../sources/source-resolution-and-runtime.md | 32 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/almanac/architecture/setup/automation-and-update.md b/almanac/architecture/setup/automation-and-update.md index 04ff09ca..68db2a8c 100644 --- a/almanac/architecture/setup/automation-and-update.md +++ b/almanac/architecture/setup/automation-and-update.md @@ -22,6 +22,18 @@ sources: type: file path: src/codealmanac/services/config/service.py note: User config writes and automation reconciliation. + - id: codex_instructions + type: file + path: src/codealmanac/integrations/setup/codex.py + note: Codex AGENTS.md managed-block installation and removal. + - id: claude_instructions + type: file + path: src/codealmanac/integrations/setup/claude.py + note: Claude guide file and import-line installation and removal. + - id: setup_tests + type: file + path: tests/test_setup_service.py + note: Tests for instruction installation, override handling, idempotence, and uninstall preservation. - id: automation_service type: file path: src/codealmanac/services/automation/service.py @@ -74,6 +86,10 @@ The request model defaults to both instruction targets, Codex as the harness, au Setup's automation policy lives outside the service. The default tasks are sync, Garden, and update. `selected_setup_tasks` reflects the three enable/disable choices, which are persisted in TOML before scheduler reconciliation [@setup_automation]. +Setup-owned instruction writes are narrow. For Codex, setup writes a managed CodeAlmanac block into `~/.codex/AGENTS.md`, or into `~/.codex/AGENTS.override.md` when that override file already has content [@codex_instructions]. For Claude, setup writes `~/.claude/codealmanac.md` and adds the `@~/.claude/codealmanac.md` import line to `~/.claude/CLAUDE.md` [@claude_instructions]. Tests keep both paths idempotent and verify uninstall removes only the setup-owned block, guide, or import line while preserving user-authored content in the same files [@setup_tests]. + +This means setup installs global agent guidance; it does not discover, merge, or rewrite repository-local instruction files. Repository instruction discovery remains outside the setup service boundary [@setup_service] [@codex_instructions] [@claude_instructions]. + ## Scheduled Jobs `AutomationService` reconciles one task, removes all tasks during full uninstall, and reports status through a `SchedulerAdapter` port [@automation_service]. Reconciliation installs a job when enabled and uninstalls it when disabled. `AutomationJobFactory` turns saved task policy into a `ScheduledJob` [@automation_service][@automation_jobs]. diff --git a/almanac/architecture/sources/source-resolution-and-runtime.md b/almanac/architecture/sources/source-resolution-and-runtime.md index 451b52a5..b6ade835 100644 --- a/almanac/architecture/sources/source-resolution-and-runtime.md +++ b/almanac/architecture/sources/source-resolution-and-runtime.md @@ -34,6 +34,30 @@ sources: type: file path: src/codealmanac/workflows/ingest/service.py note: Ingest workflow use of source resolution and runtime inspection. + - id: transcript_runtime + type: file + path: src/codealmanac/integrations/sources/transcripts/runtime.py + note: Transcript source runtime adapter. + - id: transcript_rendering + type: file + path: src/codealmanac/integrations/sources/transcripts/rendering.py + note: Transcript runtime rendering and tail truncation. + - id: transcript_tests + type: file + path: tests/test_transcript_source_runtime.py + note: Tests for Codex and Claude transcript source runtime behavior. + - id: discovery_tests + type: file + path: tests/test_transcript_discovery.py + note: Tests for transcript discovery and subagent filtering. + - id: operation_runner + type: file + path: src/codealmanac/workflows/operations/service.py + note: Lifecycle harness execution and run-event recording. + - id: harness_events + type: file + path: src/codealmanac/services/harnesses/events.py + note: Normalized harness event model used for live agent runs. --- # Source Resolution And Runtime @@ -52,6 +76,12 @@ Runtime inspection is adapter-based. `SourcesService.inspect_runtime(...)` asks Ingest uses this boundary before it renders the writing prompt. It resolves the requested inputs, records preparation events, inspects runtime snapshots, and passes both briefs and snapshots into the operation prompt [@ingest_workflow]. +## Transcript Runtime + +Transcript runtime inspection is for historical local session files selected as ingest source material. `TranscriptSourceRuntimeAdapter` supports only `SourceKind.TRANSCRIPT`, resolves the transcript path relative to the operation cwd when needed, reads readable JSONL entries, and returns a bounded text snapshot for the prompt [@transcript_runtime]. The renderer includes metadata and transcript sections, then keeps the tail when the snapshot exceeds its character budget so recent lines survive truncation [@transcript_rendering]. + +This boundary prevents a common confusion. Live lifecycle runs record normalized harness events through the operation runner, using the event model described by [Harness event shape](../../reference/harness-event-shape) [@operation_runner] [@harness_events]. Transcript source runtime turns an already-written local session file into bounded ingest material. The former records the run currently being executed, while the latter supplies past conversation evidence to an ingest prompt [@transcript_runtime]. + ## Transcript Discovery Transcript discovery is a separate source path used by sync. The default discovery set has two adapters: Claude and Codex [@transcript_adapters]. The source model has the same two transcript app values, `claude` and `codex`, so there is no separate app identity for Codex app, Claude Desktop, Claude web, or editor-specific surfaces [@source_models]. @@ -60,6 +90,8 @@ The Codex adapter scans `.codex/sessions` under the configured home directory, r Sync does not ingest every discovered transcript. It matches each transcript `cwd` to a registered repository root, skips unregistered working directories, and skips transcripts older than the active sync window as `inactive` [@sync_evaluation]. That means a transcript can be discovered correctly but still not become ingest input for the current sync run. +Tests cover Codex and Claude transcript runtime loading, missing transcript diagnostics, tail truncation, and subagent filtering during discovery [@transcript_tests] [@discovery_tests]. + ## Related Reference For source work, read [Source Material](../../concepts/source-material) first From bcc9c0ad3064f2c1ba6b5561c12373193575755d Mon Sep 17 00:00:00 2001 From: divitsheth Date: Sat, 11 Jul 2026 17:47:20 -0700 Subject: [PATCH 19/21] almanac: improve wiki routing --- almanac/README.md | 2 ++ almanac/architecture/README.md | 2 ++ almanac/getting-started.md | 11 +++++++---- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/almanac/README.md b/almanac/README.md index 4bdb6cf6..f54b8d8f 100644 --- a/almanac/README.md +++ b/almanac/README.md @@ -28,6 +28,8 @@ Begin with [Getting started](getting-started). It gives the shortest reading pat The core idea is the [local repo wiki](concepts/local-repo-wiki): a browseable Markdown wiki committed with the code, plus derived local state for search and runs. That concept explains why page identity comes from paths, why `README.md` files are landing pages, and why file evidence belongs in `sources:`. +For the product boundary, read [Local-only Python product](decisions/local-only-python-product). For exact runtime paths, read [Local state layout](reference/local-state-layout). + For implementation work, read [Architecture](architecture/) first, then follow the page for the boundary you plan to change. [Service boundaries](architecture/service-boundaries) explains how the CLI, app composition root, workflows, services, stores, ports, and integrations divide responsibility. For command behavior, use [CLI public command surface](reference/cli/public-command-surface). For config defaults and precedence, use [Config keys](reference/config-keys). ## Main Clusters diff --git a/almanac/architecture/README.md b/almanac/architecture/README.md index 72462ebf..4aa315e7 100644 --- a/almanac/architecture/README.md +++ b/almanac/architecture/README.md @@ -126,6 +126,8 @@ Start with [Service boundaries](service-boundaries). It explains the main depend [Request models](request-models) explains the typed request objects that protect service and workflow boundaries from loose dictionaries and raw CLI shapes [@request-models]. +Use [Cosmic Python translation](../reference/cosmic-python-translation) when an architecture change needs the local interpretation of service, store, port, and composition-root boundaries. + ## Page-Writing Operations [Lifecycle](lifecycle/) is the entry point for build, ingest, garden, sync, queued runs, operation execution, and mutation safety. Build, ingest, and garden are page-writing operation families; sync is a scanner that queues ingest work instead of writing pages itself [@lifecycle]. diff --git a/almanac/getting-started.md b/almanac/getting-started.md index 38196c1d..f186fc01 100644 --- a/almanac/getting-started.md +++ b/almanac/getting-started.md @@ -31,9 +31,10 @@ CodeAlmanac is a local Python product in this rewrite. It stores committed wiki Read these pages in order: 1. [Local repo wiki](concepts/local-repo-wiki) explains what the repo wiki is and why committed Markdown is separate from local derived state. -2. [Lifecycle workflows](architecture/lifecycle/workflows) explains build, ingest, and garden, and why sync is only a scanner. -3. [Index refresh and search](architecture/wiki/index-refresh-and-search) explains how read commands use the derived index. -4. [Verify a wiki change](guides/verify-a-wiki-change) explains how to check a wiki edit before calling it done. +2. [Lifecycle operation](concepts/lifecycle-operation) defines the build, ingest, and garden operation family. +3. [Lifecycle workflows](architecture/lifecycle/workflows) explains how those operations run, and why sync is only a scanner. +4. [Index refresh and search](architecture/wiki/index-refresh-and-search) explains how read commands use the derived index. +5. [Verify a wiki change](guides/verify-a-wiki-change) explains how to check a wiki edit before calling it done. That route matches the main working loop in this repository: write durable Markdown, let local services derive searchable state, and validate the result before handing work back. @@ -41,7 +42,7 @@ That route matches the main working loop in this repository: write durable Markd Start with the manual rule: evolve the codebase so the feature fits, then build the feature [@manual]. This repo treats architecture as living structure. When the current shape does not hold a feature cleanly, the expected move is to stop and flag the mismatch instead of bolting on a local workaround [@manual]. -For most implementation work, follow the architecture pages before opening individual modules. [Architecture](architecture/) gives the reading order for the architecture cluster. [Service boundaries](architecture/service-boundaries) explains the dependency direction from CLI adapters into the app, workflows, services, stores, ports, and integrations. [Lifecycle workflows](architecture/lifecycle/workflows) is the entry point for page-writing operations. [Source resolution and runtime](architecture/sources/source-resolution-and-runtime) is the entry point for ingest inputs. +For most implementation work, follow the architecture pages before opening individual modules. [Architecture](architecture/) gives the reading order for the architecture cluster. [Service boundaries](architecture/service-boundaries) explains the dependency direction from CLI adapters into the app, workflows, services, stores, ports, and integrations. [Refactoring boundaries](guides/refactoring-boundaries) turns the manual's reshape-first rule into a task guide. [Lifecycle workflows](architecture/lifecycle/workflows) is the entry point for page-writing operations. [Source resolution and runtime](architecture/sources/source-resolution-and-runtime) is the entry point for ingest inputs. ## If You Are Changing The Wiki @@ -56,7 +57,9 @@ For Garden work, also read [Wiki usefulness evaluation](concepts/wiki-usefulness Use these routes when you already know the kind of work: - For command behavior, read [CLI public command surface](reference/cli/public-command-surface). +- For adding or changing a command, read [Add a CLI command](guides/add-a-cli-command). - For config defaults, model choices, and precedence, read [Config keys](reference/config-keys). +- For setup, scheduled sync, scheduled Garden, or package update automation, read [Setup local automation](guides/setup-local-automation). - For page identity, routes, and `README.md` landing pages, read [Page identity](architecture/wiki/page-identity). - For page evidence and frontmatter, read [Frontmatter and sources](reference/page-format/frontmatter-and-sources). - For lifecycle run state, logs, and attach behavior, read [Run states and events](reference/runs/run-states-and-events). From 4f2278668eaafe3427c7f9baa7c8c6e5a4d0f01d Mon Sep 17 00:00:00 2001 From: divitsheth Date: Sat, 11 Jul 2026 18:31:24 -0700 Subject: [PATCH 20/21] almanac: clarify update source install gap --- almanac/architecture/setup/automation-and-update.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/almanac/architecture/setup/automation-and-update.md b/almanac/architecture/setup/automation-and-update.md index 68db2a8c..c9412f98 100644 --- a/almanac/architecture/setup/automation-and-update.md +++ b/almanac/architecture/setup/automation-and-update.md @@ -116,7 +116,7 @@ The editable-install guard does not cover every PEP 610 direct-url install. The Tests pin the editable-install refusal, scheduled editable skip, uv plan, and pip plan, but they do not exercise `read_direct_url` directly or prove that a pip install with `source_url` is refused [@update_tests]. Future work that broadens source-install protection should add those cases before changing `update_method`, then decide whether non-editable local directories, VCS URLs, and archives share one unsupported path or need different repair guidance. -This shape matches the active agreement: scheduled auto-update is an explicit local automation task, not a sync or Garden side effect. The agreement also states that scheduled update should skip editable installs, skip active lifecycle jobs, use a global lock, support uv tool and pip installs, and run the same two smoke checks [@live_agreement]. +This shape only partly matches the active agreement. Scheduled auto-update is an explicit local automation task, not a sync or Garden side effect, and the implementation has the global lock, active-job skip, uv and pip commands, and post-update smoke checks required by the agreement [@updates][@live_agreement]. The same agreement says scheduled update should skip editable/source installs, while the current guard skips only editable installs and lets other PEP 610 direct-url installs reach the uv or pip command path [@update_metadata][@updates][@live_agreement]. ## Uninstall From fb920f7edebbcf052f39db6ccd6596cb228754f8 Mon Sep 17 00:00:00 2001 From: divitsheth Date: Wed, 15 Jul 2026 15:47:50 -0700 Subject: [PATCH 21/21] feat: add ca CLI alias --- README.md | 8 +- RELEASE.md | 5 +- almanac/guides/release-package.md | 8 +- .../reference/cli/public-command-surface.md | 4 +- docs/plans/2026-07-15-ca-cli-alias.md | 106 ++++++++++++++++++ pyproject.toml | 1 + tests/test_public_contract.py | 8 +- 7 files changed, 128 insertions(+), 12 deletions(-) create mode 100644 docs/plans/2026-07-15-ca-cli-alias.md diff --git a/README.md b/README.md index 6e3eefda..930fbbdd 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,9 @@ uv sync uv run codealmanac --help ``` +`codealmanac` is the canonical command. Every install also provides `ca` as its +short alias, so `ca search "getting started"` is equivalent to the longer form. + Requires Python 3.12+. ## Migrating From The npm CLI @@ -459,6 +462,7 @@ default harness. `codealmanac doctor` reports harness availability. This rewrite is local-only for now. - Public command: `codealmanac` +- Short alias: `ca` - Repo wiki root: `almanac/` only - Alternate repo wiki roots: none - User state root: `~/.codealmanac/` @@ -466,10 +470,10 @@ This rewrite is local-only for now. - Storage: local markdown plus derived state under `~/.codealmanac/` - No hosted login/connect/upload commands. - No public SDK or MCP package. -- No compatibility aliases. +- No legacy compatibility aliases beyond the supported `ca` shorthand. - No alternate wiki roots. - No hidden cloud write path. -- No second wiki command name. +- No second canonical product name. This is the Python/PyPI product surface. Hosted integration can be added later around the same repo-owned wiki artifact, but it is not part of this release diff --git a/RELEASE.md b/RELEASE.md index fb5a3981..01c70656 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -101,10 +101,11 @@ Do not reuse a published version number. ## Package Surface -The package must expose exactly one public command: +The package must expose the canonical command and its short alias: ```text codealmanac +ca ``` The published artifact must include: @@ -119,7 +120,7 @@ The published artifact must include: The published artifact must not introduce: -- public `almanac` or `alm` commands +- public `almanac`, `alm`, or other undeclared command aliases - public `capture`, `login`, `connect`, or `upload` commands - public SDK or MCP modules - npm, Node, or hosted-dashboard install instructions diff --git a/almanac/guides/release-package.md b/almanac/guides/release-package.md index 77aa8608..72d84c81 100644 --- a/almanac/guides/release-package.md +++ b/almanac/guides/release-package.md @@ -9,7 +9,7 @@ sources: - id: pyproject type: file path: pyproject.toml - note: Package name, version, Python requirement, dependencies, script entrypoint, and package data. + note: Package name, version, Python requirement, dependencies, script entrypoints, and package data. - id: readme type: file path: README.md @@ -34,9 +34,9 @@ Use this guide when publishing the `codealmanac` Python package to PyPI. A relea ## Preconditions -Start from a clean checkout of the release branch. `pyproject.toml` owns the package version, requires Python 3.12 or newer, and exposes exactly one console script: `codealmanac = "codealmanac.cli.main:main"` [@pyproject]. The [public command surface](../reference/cli/public-command-surface) is the contract that release smoke should prove from installed artifacts. The release document states that stable releases publish from `main` to the normal PyPI release channel and that version numbers must not be reused [@release-doc]. +Start from a clean checkout of the release branch. `pyproject.toml` owns the package version, requires Python 3.12 or newer, and maps both the canonical `codealmanac` command and its short `ca` alias to `codealmanac.cli.main:main` [@pyproject]. The [public command surface](../reference/cli/public-command-surface) is the contract that release smoke should prove from installed artifacts. The release document states that stable releases publish from `main` to the normal PyPI release channel and that version numbers must not be reused [@release-doc]. -Keep the package surface narrow. Public-contract tests reject npm release language, old install surfaces, hosted commands, legacy aliases, and public SDK or MCP modules [@public-contract-tests]. If those tests fail, fix the public contract before publishing. +Keep the package surface narrow. Public-contract tests reject npm release language, old install surfaces, hosted commands, undeclared legacy aliases, and public SDK or MCP modules [@public-contract-tests]. If those tests fail, fix the public contract before publishing. ## Build And Smoke @@ -52,7 +52,7 @@ uv build --out-dir dist uvx twine check dist/* ``` -Then install both artifacts into clean Python 3.12 environments and smoke the installed command [@release-doc]. For product behavior, use the installed artifact command from those temporary environments or the user-facing installed `codealmanac` binary, not a command from the repo developer environment. +Then install both artifacts into clean Python 3.12 environments and smoke both installed command names [@release-doc]. Confirm that `codealmanac --version` and `ca --version` return the same version. For product behavior, use an installed artifact command from those temporary environments, not a command from the repo developer environment. Use current public syntax during smoke checks. `sync status` accepts `--wiki`, `--from`, and `--json`; it does not accept `--quiet` [@run-parser]. The release document may lag the parser, so trust parser-backed command syntax when a smoke command disagrees with the installed CLI [@release-doc] [@run-parser]. diff --git a/almanac/reference/cli/public-command-surface.md b/almanac/reference/cli/public-command-surface.md index fc660763..f0e4558b 100644 --- a/almanac/reference/cli/public-command-surface.md +++ b/almanac/reference/cli/public-command-surface.md @@ -5,7 +5,7 @@ sources: - id: pyproject type: file path: pyproject.toml - note: Package script entrypoint for the CodeAlmanac CLI. + note: Package script entrypoints for the CodeAlmanac CLI. - id: repo_readme type: file path: README.md @@ -74,7 +74,7 @@ sources: # Public Command Surface -The public command surface is the set of terminal commands exposed by the `codealmanac` script. The package installs that script as `codealmanac = "codealmanac.cli.main:main"`, so the CLI parser is the user-facing contract for command names and flags [@pyproject]. Parser modules define syntax only; the [CLI adapter boundary](../../architecture/cli/adapter-boundary) explains how parsed commands cross into services and workflows. +The public command surface is the set of terminal commands exposed by the canonical `codealmanac` script and its short `ca` alias. The package maps both console-script names to `codealmanac.cli.main:main`, so they share one parser, command behavior, output contract, and exit-code contract [@pyproject]. Parser modules define syntax only; the [CLI adapter boundary](../../architecture/cli/adapter-boundary) explains how parsed commands cross into services and workflows. The root parser registers three command families: run commands, wiki commands, and admin commands [@parser_root]. The admin family delegates to config, setup, diagnostics, update, jobs, and automation parser modules [@parser_admin]. It also exposes `--version` and lists the visible top-level command names in `PUBLIC_COMMAND_METAVAR` [@parser_root]. Hidden worker commands exist for internal scheduling and queue execution, but they are removed from visible choices and from rendered syntax guidance [@parser_run] [@syntax_catalog]. diff --git a/docs/plans/2026-07-15-ca-cli-alias.md b/docs/plans/2026-07-15-ca-cli-alias.md new file mode 100644 index 00000000..89fb6b71 --- /dev/null +++ b/docs/plans/2026-07-15-ca-cli-alias.md @@ -0,0 +1,106 @@ +# CA CLI Alias Implementation Plan + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Install `ca` as a short alias for the canonical `codealmanac` command. + +**Architecture:** Keep one CLI implementation and expose it through two Python console-script names. Both entry points target `codealmanac.cli.main:main`, so parsing, dispatch, output, errors, and exit codes remain identical without adding alias-aware runtime branches. + +**Tech Stack:** Python packaging (`pyproject.toml`), pytest, uv, Markdown public-contract documentation. + +--- + +### Task 1: Change the package entry-point contract + +**Files:** +- Modify: `tests/test_public_contract.py` +- Modify: `pyproject.toml` + +**Step 1: Write the failing test** + +Rename the entry-point contract test and require both names to target the same callable: + +```python +def test_public_entry_points_include_ca_alias(): + pyproject = tomllib.loads((PROJECT_ROOT / "pyproject.toml").read_text()) + + scripts = pyproject["project"]["scripts"] + + assert scripts == { + "ca": "codealmanac.cli.main:main", + "codealmanac": "codealmanac.cli.main:main", + } +``` + +**Step 2: Run the test to verify it fails** + +Run: `uv run pytest tests/test_public_contract.py::test_public_entry_points_include_ca_alias -q` + +Expected: FAIL because `pyproject.toml` does not yet declare `ca`. + +**Step 3: Add the minimal package entry point** + +Add the second script in `pyproject.toml`: + +```toml +[project.scripts] +ca = "codealmanac.cli.main:main" +codealmanac = "codealmanac.cli.main:main" +``` + +**Step 4: Run the focused test** + +Run: `uv run pytest tests/test_public_contract.py::test_public_entry_points_include_ca_alias -q` + +Expected: PASS. + +### Task 2: Update the public contract documentation + +**Files:** +- Modify: `README.md` +- Modify: `RELEASE.md` +- Modify: `almanac/reference/cli/public-command-surface.md` +- Modify: `almanac/guides/release-package.md` +- Modify: `tests/test_public_contract.py` + +**Step 1: Document command identity** + +Keep `codealmanac` canonical and describe `ca` as its short alias. Remove statements that the package exposes exactly one command or no compatibility aliases. + +**Step 2: Guard the README contract** + +Require the README fragment `Short alias: `ca`` in `README_REQUIRED_FRAGMENTS`. + +**Step 3: Run the public-contract tests** + +Run: `uv run pytest tests/test_public_contract.py -q` + +Expected: PASS. + +### Task 3: Verify the built artifacts + +**Files:** +- Verify only: repository and temporary build/install directories + +**Step 1: Run repository gates** + +Run: `uv run pytest && uv run ruff check . && git diff --check` + +Expected: all tests pass, Ruff reports no errors, and Git reports no whitespace errors. + +**Step 2: Build and inspect artifacts** + +Run: `uv build --out-dir ` + +Expected: wheel and source distribution build successfully. + +**Step 3: Smoke both installed commands** + +Install the wheel into a temporary virtual environment, then run: + +```bash +codealmanac --version +ca --version +``` + +Expected: both commands exit zero and print the same CodeAlmanac version. diff --git a/pyproject.toml b/pyproject.toml index c0317cd2..33c552cc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,6 +42,7 @@ dependencies = [ ] [project.scripts] +ca = "codealmanac.cli.main:main" codealmanac = "codealmanac.cli.main:main" [project.urls] diff --git a/tests/test_public_contract.py b/tests/test_public_contract.py index 4dd593d0..b6e7bb05 100644 --- a/tests/test_public_contract.py +++ b/tests/test_public_contract.py @@ -34,6 +34,7 @@ README_REQUIRED_FRAGMENTS = ( "Public command: `codealmanac`", + "Short alias: `ca`", "Repo wiki root: `almanac/` only", "Alternate repo wiki roots: none", "User state root: `~/.codealmanac/`", @@ -130,12 +131,15 @@ ) -def test_public_entry_point_is_codealmanac_only(): +def test_public_entry_points_include_ca_alias(): pyproject = tomllib.loads((PROJECT_ROOT / "pyproject.toml").read_text()) scripts = pyproject["project"]["scripts"] - assert scripts == {"codealmanac": "codealmanac.cli.main:main"} + assert scripts == { + "ca": "codealmanac.cli.main:main", + "codealmanac": "codealmanac.cli.main:main", + } def test_python_package_metadata_declares_readme_and_license():