9.8 KiB
Created as a follow-up to the closed manifest profiles work item after reviewing the original intent and the current built-in Nix profile shape.
Implementation plan written to artifacts/implementation-plan.md. Key recommendation: introduce a typed semantic profile artifact and manifestization step, move/centralize model catalog context-window resolution so compaction can derive from model metadata, and resolve builtin profiles in-process so normal default startup does not require external nix.
Plan
Implementation direction
Use the worktree + sibling coder/reviewer flow. The investigation Pod found the main boundary issue to be concentrated in crates/manifest/src/profile.rs: profile artifacts are currently deserialized as PodManifestConfig, while built-in Nix files expose a manifest-shaped authoring API.
Decisions for the implementation pass:
- Move data-only model catalog resolution to a cycle-free place owned by
manifestso profile manifestization can derive context-window-dependent settings. Keep live provider/client construction inprovider. - Introduce a semantic profile artifact format such as
insomnia.semantic-profile.v1; top-level semantic artifacts must useprofilemetadata pluspolicy, notmanifest/config. - Resolve built-in
defaultin-process so the normal default startup path does not require an externalnixcommand. User/project/path Nix profiles may still requirenix evalwith clear diagnostics. - Remove
pod.namefrom built-in profiles. Direct no-arginsomnia-podshould preserve the current effective default Pod nameinsomniaas runtime input, while--profile-pod-nameremains the explicit fresh-spawn override. - Do not preserve manifest-shaped Nix profiles as the normal authoring API.
--manifestremains the low-level concrete manifest escape hatch. - Keep the initial semantic policy narrow: explicit model ref, explicit reasoning effort, workspace scope policy, compaction ratios/preset derived from effective context window, memory/session/web policy sufficient to reproduce current builtin behavior.
- Update docs and tests so built-in examples no longer recommend
mkManifestor raw manifest-shaped profiles.
Implementation should remain narrow: preserve existing profile selection semantics, source-qualified selectors, ambiguity errors, TUI/client profile selection flow, and SpawnPod.scope authority.
Decision
Implementation is paused after design discussion. The attempted direction of introducing a semantic JSON-profile-to-Manifest projection is not accepted as the specification: it risks preserving nearly the same information as Manifest and therefore failing the intended abstraction.
The current design question has been split into profile-authoring-requirements-sync, which records the shared requirements and open questions before choosing Lua/external Nix/another authoring language. Do not proceed with the existing child-worktree implementation until that specification is decided.
Closed
id: 20260529-222850-semantic-nix-profiles slug: semantic-nix-profiles title: Make Nix profiles semantic and manifestize them in the resolver status: closed kind: task priority: P2 labels: [manifest, profiles, nix, architecture] created_at: 2026-05-29T22:28:50Z updated_at: 2026-05-30T03:52:39Z assignee: null legacy_ticket: null
Background
The closed manifest profiles work item (work-items/closed/20260527-000022-manifest-profiles) introduced profile discovery/selection, built-in profile files, and Nix evaluation as the profile artifact path. Its original direction described profiles as role/model/policy selections that resolve into a precise runtime manifest. The current built-in Nix shape has drifted from that intent: it effectively asks authors to write a Manifest-shaped object in Nix.
Current examples include:
resources/nix/profile-lib.nixexposesmkProfileand amkManifesthelper, wheremkManifestis currently an identity function.resources/nix/profiles/default.nixusesinsomnia.mkProfile { manifest = insomnia.mkManifest { ... }; }.- The built-in profile currently contains low-level or instance-specific Manifest fields such as
pod.name = "insomnia". - Model policy fields such as high reasoning effort and compaction thresholds are represented as low-level manifest settings rather than being derived from a profile's model/context policy.
- Profile evaluation currently shells out to
nix evalfor Nix artifacts, so the boundary between profile language support and a runtime dependency on thenixcommand is unclear.
The issue is not that profile artifacts are eventually serialized as manifests. The issue is that the authoring API currently exposes the output shape as if the profile itself were a manifest. Profiles should be semantic, and the resolver should perform the manifestization step.
Goal
Redesign the Nix profile authoring surface so profiles express role/model/tool/context policy at the appropriate level of abstraction, and the manifest resolver turns that semantic profile into the concrete runtime manifest/config used to start a Pod.
This should restore the intended boundary:
- Profile: selectable role/policy/model/context/tool behavior.
- Resolver/manifestization: derives concrete defaults and token thresholds from model metadata and profile policy.
- Runtime manifest/config: low-level concrete values consumed by Pod startup.
Desired direction
- Remove
mkManifestfrom the public/built-in authoring style. A profile should not look likemkProfile { manifest = mkManifest { ... }; }. - Built-in profiles should be written as semantic profiles, not Manifest-shaped blobs.
- Instance-specific values such as
pod.namemust not live in built-in profiles. Pod names come from CLI/TUI/SpawnPod creation, not profile identity. - Model behavior such as reasoning effort belongs to the profile's model/quality policy and should be manifestized into provider-specific request config by the resolver.
- Compaction and context budgeting should be derived from the selected model's context window and profile policy, e.g. ratios/multipliers/strategy names, rather than hard-coded token thresholds copied into the profile.
- Nix evaluation should be treated as a profile authoring/evaluation mechanism, not as a requirement that the runtime default path always depends on an external
nixcommand.
Acceptance criteria
- Audit the original manifest profiles work item and current implementation to identify where the implementation became Manifest-shaped instead of semantic-profile-shaped.
- Replace the built-in Nix profile shape with a semantic profile API. The exact field names may be redesigned, but they must clearly distinguish profile policy from runtime manifest output.
- Remove
pod.nameand any other instance-specific Pod identity/configuration from built-in profiles. - Remove
mkManifestfrom built-in examples and docs. If a compatibility helper remains internally, it must not be the recommended authoring API and must be justified. - Implement or adjust the resolver so semantic profile data is manifestized into the concrete runtime manifest/config.
- Ensure model-derived settings are resolved in one place. In particular, reasoning effort and context/compaction policy should be interpreted as profile/model policy and converted into concrete request/compaction settings by the resolver.
- Add or update model catalog/context-window plumbing as needed so compaction thresholds can be derived from the selected model rather than duplicated as raw profile constants.
- Decide and document the Nix evaluator boundary:
- built-in/default profiles must not require the external
nixcommand at normal runtime unless that dependency is deliberately accepted and documented; - user/project Nix profiles may use
nix evalif no lightweight in-process evaluator is chosen, but diagnostics must clearly state that Nix is required for Nix-authored profiles; - do not silently make all profile selection depend on a missing or slow
nixbinary.
- built-in/default profiles must not require the external
- Investigate whether a lightweight embedded evaluator is practical enough for the supported Nix subset. If it is not, document why and keep the external-command dependency isolated to Nix-authored profile evaluation.
- Preserve previous profile selection semantics where still relevant: built-in/user/project profile discovery, default profile selection, source-qualified selectors, ambiguity errors, and manifest cascade removal.
- Update docs/tests so the examples present profiles as semantic policy, not manifests written in Nix syntax.
- Add tests covering:
- built-in profile manifestization without
pod.name; - semantic compaction policy derived from model context window;
- reasoning/model policy manifestization;
- missing
nixcommand behavior for user/project Nix profiles, if external evaluation remains; - no regression in profile discovery/default/source-qualified selection.
- built-in profile manifestization without
- Run focused validation for the manifest crate and any affected pod/tui/client paths, plus
./tickets.sh doctorandgit diff --check.
Non-goals
- Do not reintroduce manifest cascade or manifest overlay selection as a replacement for profiles.
- Do not turn Nix profiles into a general low-level manifest DSL.
- Do not add profile alias registry complexity back unless a separate ticket re-justifies it.
- Do not implement encrypted secret storage here; keep it in the existing encrypted secrets work item.
- Do not require solving every possible provider-specific model option in this ticket; implement the minimum necessary semantic-to-runtime mapping and leave explicit follow-ups for broader model policy coverage.