Plan: Make Operator-Skill State Immutable and Verifiable
Plan: Make Operator-Skill State Immutable and Verifiable
Plan State
- Status: Complete; manually converged onto the current Effect v4 architecture
- Scope: IP-322 with every IP-340, IP-341, and IP-342 acceptance signal
- Port mode: manual convergence from the accepted source branch
- Current ownership: domain policy under
apps/cli/src/features/operator-skill, Skills CLI mechanics underapps/cli/src/integrations, and composition through application, port, platform, and runtime-config boundaries - Integration state: parent-owned; branch publication and coordinated integration checks were not rerun in this slice
- Current validation: 133/133 focused operator/integration/command tests plus 15/15 public-output/brand tests, 148/148 total; mutation and migration passed 66/66; build and typecheck passed; Effect validators passed 93/93 with 1,352 expectations; full CLI passed 626/626 across 56 files; build emitted 526 modules; corrected diff plus untracked set passed lint across 48 TypeScript files
Initial Situation
Source-branch history: executable maintenance previously combined operator discovery, permissive Skills CLI parsing, and mutation policy. A failed listing could become false absence, installs could follow a moving source, and process exit could be mistaken for verified mutation. Those historical RED conditions motivated the feature boundary; they do not describe the converged architecture.
IP-319/IP-330 already characterizes the public hi operator and deprecated alias seams. This epic replaces the internals without changing operator-skill state into scaffold, baseline, executable-upgrade, or project-pack state.
Proposed Solution Shape
Build one feature-owned operator-skill lifecycle. IP-340 defines immutable target identity and CLI compatibility resolution. IP-341 independently defines installed-copy inspection, current-directory plus active-agent precedence, and explicit detection failures. One typed Skills CLI integration adapter implements external command syntax, JSON decoding, version gating, timeouts, agent binding, and subprocess error normalization. Skills CLI remains the sole discovery authority. After successful JSON listing, only the adapter may read the exact files named by the frozen target manifest below each reported canonical skill path; no scan or filesystem discovery fallback exists.
After both roots are green, IP-342 sequences install, update, and migration as independently verified scope actions. Every successful-looking write is re-inspected. Successful scopes remain successful when peers fail. Legacy removal occurs only after all affected fallbacks have verified compatible replacements. The command layer returns structured status, failures, exact retries, and reload guidance through the presentation contract, while the existing hi skills rename compatibility alias only delegates to the lifecycle and receives no rename redesign.
Locked Decision Ledger
| Decision | Status | Planning consequence |
|---|---|---|
| Shared Devpunks skills is authoritative | Locked | Target metadata names that source; this epic does not edit or synchronize it. |
| Target identity is immutable and CLI-compatible | Locked | Resolution returns exact version, revision, source, and compatibility; no moving main. |
| IP-340 and IP-341 are independent roots | Locked | T1 and T2 start together and both must pass before lifecycle mutation work. |
| Local overrides global only inside its project | Locked | T2 resolves current-directory and active-agent effective copy and lists shadowed copies. |
| Global default always exists after install | Locked | A local copy never suppresses global-default creation. |
| Detection failure is not absence | Locked | Adapter and lifecycle use typed unavailable/list/parse/timeout failures. |
| Every mutation is observed and verified | Locked | Process exit alone never marks a scope successful. |
| Partial success remains changed and truthful | Locked | No cross-scope rollback; per-scope result and exact retry are mandatory. |
| Legacy removal follows verified replacement | Locked | Migration removal is gated per affected fallback after replacement verification. |
| One typed Skills CLI adapter owns mechanics | Locked | No command/domain subprocesses, parsing, scans, or filesystem discovery fallback. |
| Operator lifecycle stays independent | Locked | No pack, scaffold, baseline, executable-upgrade, sync, release-baseline, or rename work. |
| One coordinated delivery line | Locked | PR base is the parent architecture branch; never target or merge main. |
Assumptions and Constraints
- IP-330 readiness is preserved by the accepted IP-319 implementation evidence.
- IP-340 and IP-341 have no dependency on each other. Both natively block IP-342.
- Exact compatibility encoding and selected immutable release/commit are implementation tuning. T1 freezes an explicit compatible target at implementation start and tests identity reproducibility.
- The current public commands remain
hi operator status|install|update|migrate. No new scope flags are required. - The existing
hi skills renamedeprecated alias remains only as characterized compatibility behavior. This plan does not add rename behavior or touch shared skill content. - The external Skills CLI is the sole installation/inspection integration. Missing, malformed, timed-out, or unsuccessful calls are typed failures.
- Tests use deterministic Layers and run-owned temporary working directories. They do not mutate real global skills, project skills, agents, or the shared source repository.
- Planning performs no Linear mutation. Story state changes only after implementation evidence exists.
Story and Acceptance Mapping
| Story | Acceptance group | Tasks | Final proof |
|---|---|---|---|
| IP-340 | Immutable shared-source target and explicit CLI compatibility | T1, T3, T4 | Resolver fixtures plus exact source/version/revision status |
| IP-340 | Repeated resolution returns the same identity | T1, T4 | Deterministic resolver and packaged status evidence |
| IP-341 | Global default plus intentional local-over-global precedence | T2, T4 | Scope matrix for inside/outside project and active agents |
| IP-341 | Effective and shadowed copies are visible | T2, T4, T7 | Read-model and public command assertions |
| IP-341 | Detection/list failures stay typed | T2, T3, T4 | Adapter failure fixtures and no-false-absence tests |
| IP-342 | Verify each apparently successful mutation | T5, T6 | Re-inspection traces and mismatched-result failures |
| IP-342 | Preserve and report partial success with exact retries | T5, T7 | Mixed-scope public result fixtures |
| IP-342 | Remove legacy only after verified replacement | T6 | Ordered call trace and refusal tests |
| IP-342 | Successful writes emit reload guidance | T5, T6, T7 | Full and partial-success output assertions |
| IP-322 | Typed feature boundary and one Skills CLI adapter | T1-T7 | Import guards, deterministic Layer, packaged proof |
Codebase Findings
apps/cli/src/integrations/cli-maintenance.tsownsInstalledSkill, operator presence/result booleans, list parsing, moving-source commands, subprocesses, and mutation orchestration beside executable update code.listSkillsmaps every nonzero list result to[], conflating unavailable/broken detection with absence.manageHiCliSkilltrusts write exit codes, does not re-inspect, and may remove both legacy scopes after only one global replacement.hi operator installcurrently installs global only when no copy exists, so a project-local copy suppresses the required global fallback.apps/cli/src/cli/operator-command.tsprints inferred booleans and constructs retry commands from core helpers; it cannot distinguish failed, unverified, incompatible, effective, or shadowed state.apps/cli/src/integrations/cli-maintenance.test.ts,apps/cli/src/cli/operator-command.test.ts, andapps/cli/src/cli/public-output-contract.test.tsare the existing focused and packaged behavior seams.apps/cli/test-fixtures/public-output/command-modes.jsoncharacterizes operator status/install/update/migrate and the deprecated alias.- Operator workflow documentation is owned by
docs/README.md,docs/runbooks/hi-cli-scaffolding.md, and routed CLI command/product-foundation pages.
Dependency Readiness
- Status: No Stack Required
- Dependency: IP-330
- Evidence:
apps/wiki/content/docs/project/specs/cli/IP-319-establish-one-comprehensive-behavior-contract/IMPLEMENTATION-NOTES.mdrecord accepted characterization evidence; IP-330 is Done. - Reason: IP-340 and IP-341 may begin from the shared gate. Both must complete before IP-342; that is internal task order, not PR-stack topology.
Branch/Base Intent
- Use an IP-322-specific implementation branch/worktree derived from
team/stefan/refactor-cli-architecture. - Open or update the IP-322 PR with base
team/stefan/refactor-cli-architecture. - Never target
main, merge the coordinated architecture line, or deploy from this epic. - Keep all child-story work in one PR; do not create stacked IP-340/IP-341/IP-342 PRs.
Dependency Graph
[T1 (IP-340), T2 (IP-341)] -> T3 -> T4 -> T5 -> T6 -> T7 -> T8 -> T9T1 and T2 are independent roots with disjoint files. T3 implements their shared typed integration seam. T4 closes both read-side roots. Only then may T5/T6 implement IP-342 mutations.
Parallel Execution Waves
| Wave | Tasks | Start condition | Write-scope rule |
|---|---|---|---|
| 1 | T1, T2 | Immediately after plan approval | Immutable-target files vs installed-scope files; no overlap |
| 2 | T3 | T1 and T2 green | Skills CLI adapter only |
| 3 | T4 | T3 green | Read-only lifecycle/status composition |
| 4 | T5 | T4 green | Install/update mutation policy |
| 5 | T6 | T5 green | Migration/legacy-removal policy |
| 6 | T7 | T6 green | CLI/public seam and old-core deletion |
| 7 | T8 | T7 green | Docs-ingest only |
| 8 | T9 | T8 green | Parent validation/review only |
Tasks
T1: Resolve one immutable CLI-compatible operator target
- depends_on: []
- location:
apps/cli/src/features/operator-skill/target.ts;apps/cli/src/features/operator-skill/target.test.ts;apps/cli/src/features/operator-skill/test-fixtures/targets.json - description: Define the IP-340 target record and pure resolver. Each target carries the authoritative shared Devpunks source, exact operator-skill version, immutable released revision or commit, and explicit compatibility with the active CLI. Select and freeze the implementation-start compatible target; reject moving refs, ambiguous matches, incompatible CLI versions, and incomplete identities.
- validation: Deterministic fixtures prove exact compatible selection, same-input identity reproducibility, incompatible/no-target typed failures, and rejection of
main, branch-only, or missing revision targets. - status: Completed
- log: Test-drove a pure immutable-target resolver. Production exports the frozen implementation-start
hi-cliidentity at shared-skills commit45072f4721d9668177bc4dd006802935ae61e70f, version1.0.0, compatible with CLI>=2.6.1 <3.0.0. Bounded history proves that revision renamed the skill and path fromdp-clitohi-cli; laterb705dfdonly added operator-flow guidance. The resolver accepts candidates only when every identity field equals production authority, returns the frozen production target without caller aliasing, and preserves typed invalid/no-match/ambiguous outcomes. - files edited/created:
apps/cli/src/features/operator-skill/target.ts;apps/cli/src/features/operator-skill/target.test.ts;apps/cli/src/features/operator-skill/test-fixtures/targets.json;apps/wiki/content/docs/project/specs/cli/IP-322-operator-skill-state/PLAN.md;apps/wiki/content/docs/project/specs/cli/IP-322-operator-skill-state/IMPLEMENTATION-NOTES.md - backlog_item_id: IP-340
- backlog_item_url: https://linear.app/devpunks/issue/IP-340/resolve-a-reproducible-operator-skill-target
- relation_mode: native
- assigned_skills: [
autoreview,codebase-design,effect-authoring,effect-backend-structure,effect-best-practices,effect-recoverable-actions,improve-codebase-architecture,parallel-research,quality-types,simplify,swarm-planner,tdd,turborepo] - tdd_status: required
- tdd_target: No production resolver currently returns an immutable source/version/revision/compatibility identity or rejects a moving source.
- red_command:
bun run --cwd apps/cli test -- src/features/operator-skill/target.test.ts - expected_red_failure: The authored assertions observe a moving or incomplete target, or no exact target identity, instead of the expected immutable source/version/revision compatible with the active CLI.
- green_command:
bun run --cwd apps/cli test -- src/features/operator-skill/target.test.ts && bun run --cwd apps/cli check-types - reason_not_testable:
- red_evidence: Initial implementation RED:
bun run --cwd apps/cli test -- src/features/operator-skill/target.test.tsexited 1 because./targetdid not exist. Incremental implementation REDs observed moving/incomplete/non-authoritative targets resolving, incompatible targets resolving, and two compatible targets selecting the first identity. Review-fix REDs observed the missing production authority export, resolved target aliasing caller input, source/revision mismatch collapsing toMovingRevision, and an arbitrary version resolving as authoritative. Added malformed-version and maximum-exclusive boundary tests passed immediately against existing validation; no RED was manufactured for already-correct behavior. - green_evidence:
bun run --cwd apps/cli test -- src/features/operator-skill/target.test.tspassed 16/16;bun run --cwd apps/cli check-typespassed. - codebase_design_notes: Target resolution is pure policy. It hides compatibility encoding behind one small resolver and makes moving-source identity unrepresentable in the accepted result.
- review_mode: cli
- runtime_validation: not_required
- runtime_target: not_applicable
- runtime_evidence: not_applicable
- runtime_cleanup: not_applicable
T2: Resolve effective, shadowed, and failed installed-copy state
- depends_on: []
- location:
apps/cli/src/features/operator-skill/installed-state.ts;apps/cli/src/features/operator-skill/installed-state.test.ts;apps/cli/src/features/operator-skill/test-fixtures/installed-copies.json - description: Define the IP-341 copy/read model and pure precedence resolver. Model global and project-local copies with version, source, revision, compatibility, project root, and bound agents. Resolve the effective copy for current directory plus active agent, preserve the global fallback outside the project, enumerate every shadowed copy, and represent detection failure separately from absence.
- validation: Matrix covers global only, local plus global inside/outside the project, multiple agents, incompatible copies, shadowed duplicates, no copy, and typed project/global listing failure.
- status: Completed
- log: Test-drove a pure installed-copy precedence resolver. The read model carries exact installed identity, compatibility, global/project-local scope, project root, and bound agents. Project-local copies override the global fallback only for an active bound agent inside that project; incompatible effective copies and every active shadowed duplicate remain visible. Distinct same-scope top candidates return deterministic
Ambiguousstate rather than arbitrary selection. Every exposed non-semantic collection is identity-sorted, including incompatible, shadowed, detected, failure, and bound-agent collections. The enclosing project inspection owns project-root authority: equivalent roots normalize to it and contradictions return typedProjectRootMismatch. Successful empty detection returnsAbsent, while listing/integrity failures returnDetectionFailedwith partial detected evidence and never resolve an effective copy. Effect Schema decodes the raw JSON fixture without discriminator rewriting. - files edited/created:
apps/cli/src/features/operator-skill/installed-state.ts;apps/cli/src/features/operator-skill/installed-state.test.ts;apps/cli/src/features/operator-skill/test-fixtures/installed-copies.json;apps/wiki/content/docs/project/specs/cli/IP-322-operator-skill-state/PLAN.md;apps/wiki/content/docs/project/specs/cli/IP-322-operator-skill-state/IMPLEMENTATION-NOTES.md - backlog_item_id: IP-341
- backlog_item_url: https://linear.app/devpunks/issue/IP-341/resolve-effective-global-and-project-local-operator-copies
- relation_mode: native
- assigned_skills: [
autoreview,codebase-design,effect-authoring,effect-backend-structure,effect-best-practices,effect-recoverable-actions,improve-codebase-architecture,parallel-research,quality-types,simplify,swarm-planner,tdd,turborepo] - tdd_status: required
- tdd_target: Current presence booleans cannot express effective copy, active-agent binding, shadowing, compatibility, or detection failure.
- red_command:
bun run --cwd apps/cli test -- src/features/operator-skill/installed-state.test.ts - expected_red_failure: The authored matrix observes presence booleans or false absence instead of the expected effective copy, shadowed copies, active-agent binding, compatibility, and distinct detection failure.
- green_command:
bun run --cwd apps/cli test -- src/features/operator-skill/installed-state.test.ts && bun run --cwd apps/cli check-types - reason_not_testable:
- red_evidence: Initial RED:
bun run --cwd apps/cli test -- src/features/operator-skill/installed-state.test.tsexited 1 because./installed-statedid not exist. Incremental REDs then proved global-first selection incorrectly ignored the inside-project local override and a successful empty inspection threw instead of returningAbsent; the global failure fixture crashed as if it were copy data instead of remaining a typed failure. Review-fix REDs proved distinct reversed global/project-local candidates were selected by input order, a copy root contradicting its inspection silently fell back to global, malformed raw fixture scope reached an undefined decoder instead of a typed schema boundary, and reversed incompatible candidates changed the fullAmbiguousstate becauseincompatiblepreserved input order. - green_evidence: Exact GREEN command passed:
bun run --cwd apps/cli test -- src/features/operator-skill/installed-state.test.ts && bun run --cwd apps/cli check-types(14/14 tests, TypeScript clean). Focused Oxfmt andgit diff --checkpassed. Each untracked T2 artifact also passedgit diff --no-index --check /dev/null <file>by producing no whitespace diagnostic with the expected no-index diff exit 1. Focused Oxlint was environment-blocked before file analysis because the existing@effect/eslint-plugininstall cannot resolve@typescript-eslint/utils. Three required autoreview attempts, including the final review-fix patch, were environment-blocked because installed Codex0.139.0cannot run configured modelgpt-5.6-sol. - codebase_design_notes: Precedence is one pure feature seam, independent of Skills CLI syntax and mutation. Discriminated scope, compatibility, and result unions make global/project-local copies and
Resolved/Absent/DetectionFailed/Ambiguousstates explicit. An effective copy exists only when the highest-precedence identity is singular; detection and integrity failures preserve partial evidence without producing an effective result. The enclosing inspection is the sole project-root authority. - review_mode: cli
- runtime_validation: not_required
- runtime_target: not_applicable
- runtime_evidence: not_applicable
- runtime_cleanup: not_applicable
T3: Implement one typed Skills CLI integration adapter
- depends_on: [T1, T2]
- location:
apps/cli/src/features/operator-skill/port.ts;apps/cli/src/integrations/skills-cli.ts;apps/cli/src/integrations/skills-cli.test.ts;apps/cli/src/features/operator-skill/test-fixtures/skills-cli/*.json - description: Add the only external Skills CLI port and live Layer. Own the Skills CLI
>=1.5.17gate, list/install/remove syntax, JSON decoding, timeouts, working directory, global/project scope, active-agent binding, subprocess normalization, and adapter-only content verification. Install immutable target URLs/revisions supplied by T1. After successful JSON discovery, verify only the exact files in the target's immutable SHA-256 manifest below each CLI-reported path. Return typed unavailable, timeout, exit, unsupported-version, malformed-output, binding, unsafe-path, missing, unreadable, malformed-manifest, and identity-mismatch failures. Never parse human output, scan directories, or use filesystem discovery fallback. - validation: Deterministic process fixtures cover both scopes, agents, immutable add/remove arguments, version gating, exact manifest identity, effective CLI-reported paths, canonical containment across leaf and intermediate-directory symlinks, partial verified evidence, malformed JSON, nonzero exit, timeout, missing executable, binding mismatch, unsafe/missing/unreadable paths, malformed manifests, identity mismatch, and decoy paths; import guards keep subprocess mechanics out of feature and command modules.
- status: Completed
- log: Added the sole typed Skills CLI port and live Layer, then reconciled it to accepted option B. The adapter probes official Skills CLI
>=1.5.17before every operation, uses JSON list output as the sole enumeration/path/scope authority, and reads only exact immutable manifest files whose canonical paths remain below the canonical reportedhi-cliroot. Verified copies receive source, version, revision, and compatibility; failures retain typed partial verified evidence. No glob, directory walk, filesystem write, human-output parser, or discovery fallback exists. Hermetic scoped fixtures use a run-owned fake executable, exact copied payloads, decoys, reported paths, symlink escapes, and trace; cleanup owns the full temp root and timeout process. T4-T9 remain planned. - files edited/created:
apps/cli/src/features/operator-skill/target.ts;apps/cli/src/features/operator-skill/target.test.ts;apps/cli/src/features/operator-skill/port.ts;apps/cli/src/integrations/skills-cli.ts;apps/cli/src/integrations/skills-cli.test.ts;apps/cli/src/features/operator-skill/test-fixtures/skills-cli/cases.json;apps/wiki/content/docs/project/specs/cli/IP-322-operator-skill-state/PLAN.md;apps/wiki/content/docs/project/specs/cli/IP-322-operator-skill-state/IMPLEMENTATION-NOTES.md - backlog_item_id: IP-322
- backlog_item_url: https://linear.app/devpunks/issue/IP-322/make-operator-skill-state-immutable-and-verifiable
- relation_mode: native
- assigned_skills: [
autoreview,codebase-design,effect-authoring,effect-backend-structure,effect-best-practices,effect-recoverable-actions,improve-codebase-architecture,parallel-research,quality-types,simplify,swarm-planner,tdd,turborepo] - tdd_status: required
- tdd_target: Existing subprocess/list parsing returns booleans or empty arrays and follows a moving source.
- red_command:
bun run --cwd apps/cli test -- src/integrations/skills-cli.test.ts - expected_red_failure: The authored adapter assertions observe moving-source argv, boolean/empty-list failure collapse, or untyped subprocess output instead of immutable arguments and the expected typed unavailable/timeout/exit/parse/binding failures.
- green_command:
bun run --cwd apps/cli test -- src/integrations/skills-cli.test.ts && bun run --cwd apps/cli check-types - reason_not_testable:
- red_evidence: Initial RED exited 1 because
./skills-clidid not exist. Option-B RED then exited 1 with 10/14 failures proving missing identity enrichment, version preflight, mismatch/path/manifest verification, partial verified evidence, and mutation gates. Incremental empty-manifest RED exited 1 with 1/16 failures because an empty receipt incorrectly asserted identity. Review RED exited 1 with 2/18 failures because matching content escaped through leaf and intermediate-directory symlinks. - green_evidence:
bun run --cwd apps/cli test -- src/integrations/skills-cli.test.ts && bun run --cwd apps/cli check-typesexited 0; the focused suite passed 18/18 andtsc --noEmitpassed. The combined target/adapter regression passed 35/35 plus typecheck. - codebase_design_notes: The service interface stays small and the live adapter hides external mechanics. The frozen target owns a deeply frozen three-file SHA-256 manifest. Feature code sees CLI-decoded paths, identity-enriched verified copies, and typed failures with partial verified evidence. Filesystem access is a narrow verification step inside the adapter after successful CLI discovery. Both the reported root and every literal manifest file are canonicalized, and containment is rechecked before content is read; this never becomes a second discovery path.
- review_mode: cli
- runtime_validation: required
- runtime_target: Run-owned fake
skillsexecutable and temporary project roots; never the real global Skills CLI state. - runtime_evidence: Captured argv/cwd/stdout/stderr/status prove the version preflight, immutable arguments, scope, agent binding, decoding, timeout, and typed subprocess mapping. Run-owned payloads prove exact-file success, mismatch, unsafe/missing/unreadable paths, malformed manifests, partial verified evidence, refusal to use a valid decoy, and rejection of matching content reached through leaf or intermediate-directory symlink escapes.
- runtime_cleanup: Use a unique OS-temp root and PATH entry; terminate spawned processes; remove only run-owned scripts/projects; assert no process or temp root remains.
T4: Compose immutable target and effective status lifecycle
- depends_on: [T3]
- location:
apps/cli/src/features/operator-skill/lifecycle.ts;apps/cli/src/features/operator-skill/lifecycle-status.test.ts;apps/cli/src/features/operator-skill/test-layers.ts - description: Compose T1-T3 into the feature-owned read boundary.
statusresolves the active CLI's immutable compatible target, inspects project and global scopes through the adapter, and returns every installed identity, compatibility result, effective copy, shadowed copies, legacy copies, and typed inspection failures. A project-local copy never hides the global state. - validation: Deterministic Layers prove repeatable IP-340 identity and IP-341 precedence across directory/agent combinations; adapter failure remains failure; incompatible and shadowed copies remain visible.
- status: Complete
- log: 2026-07-18 — Added the Effect lifecycle read boundary over the frozen target and typed Skills CLI port. Both scopes are always inspected; compatible, incompatible, effective, shadowed, legacy, failed, and partial verified evidence remain explicit.
- files edited/created:
apps/cli/src/features/operator-skill/lifecycle.ts;apps/cli/src/features/operator-skill/lifecycle-status.test.ts;apps/cli/src/features/operator-skill/test-layers.ts;apps/wiki/content/docs/project/specs/cli/IP-322-operator-skill-state/PLAN.md;apps/wiki/content/docs/project/specs/cli/IP-322-operator-skill-state/IMPLEMENTATION-NOTES.md - backlog_item_id: IP-340, IP-341
- backlog_item_url: https://linear.app/devpunks/issue/IP-340/resolve-a-reproducible-operator-skill-target; https://linear.app/devpunks/issue/IP-341/resolve-effective-global-and-project-local-operator-copies
- relation_mode: native
- assigned_skills: [
autoreview,codebase-design,effect-authoring,effect-backend-structure,effect-best-practices,effect-recoverable-actions,improve-codebase-architecture,parallel-research,quality-types,simplify,swarm-planner,tdd,turborepo] - tdd_status: required
- tdd_target: No lifecycle returns immutable desired identity alongside truthful effective, shadowed, incompatible, legacy, and failed observed state.
- red_command:
bun run --cwd apps/cli test -- src/features/operator-skill/lifecycle-status.test.ts - expected_red_failure: The authored lifecycle assertions receive incomplete boolean status or false absence instead of the expected immutable target, effective/shadowed copy set, compatibility, legacy state, and typed inspection failure.
- green_command:
bun run --cwd apps/cli test -- src/features/operator-skill/target.test.ts src/features/operator-skill/installed-state.test.ts src/integrations/skills-cli.test.ts src/features/operator-skill/lifecycle-status.test.ts && bun run --cwd apps/cli check-types - reason_not_testable:
- red_evidence: Initial RED exited 1 because
./lifecycledid not exist. The partial-evidence RED then exited 1 with 1/4 failures becauseSkillsCliVerificationFailure.verifiedSkillswas discarded instead of remaining detected alongside the typed inspection failure. - green_evidence: The exact combined command exited 0: target 17/17, installed-state 14/14, live adapter 18/18, and lifecycle 4/4 (53/53 total), followed by successful
tsc --noEmit. - codebase_design_notes: This closes both independent read roots before mutation. Policy depends only on the typed port; no command rendering, subprocess, filesystem, scaffold, baseline, or executable update dependency enters the feature. The lifecycle always asks for global and project scope, normalizes adapter evidence once, and feeds the existing pure installed-state resolver. Typed failures retain partial verified copies without becoming false absence or an invented effective state.
- review_mode: cli
- runtime_validation: not_required
- runtime_target: not_applicable
- runtime_evidence: not_applicable
- runtime_cleanup: not_applicable
T5: Verify install and update with truthful partial success
- depends_on: [T4]
- location:
apps/cli/src/features/operator-skill/lifecycle-mutation.ts;apps/cli/src/features/operator-skill/lifecycle-mutation.test.ts - description: Implement IP-342 install/update policy. Install always ensures the global default even when a project-local copy exists. Default update targets every detected
hi-cliscope. After each successful-looking adapter mutation, re-inspect and accept success only when source, version, revision, compatibility, scope, and agent binding match the target. Preserve independent successes; return typed failed/unverified actions, exact retries, and reload guidance for any successful write. - validation: Cases cover local-only install creating global, all-scope update, mismatched post-state, inspection failure after write, one-scope process failure, mixed verified/unverified results, exact retry per scope, and no rollback.
- status: Complete
- log: 2026-07-18 — Added a sequential Effect mutation ledger over the T4 read model. Install ensures global and leaves an already verified target unchanged. Update selects every detected scope, verifies immediately after each successful write, retains verified peers beside typed failed or unverified actions, and emits immutable per-scope retry evidence plus reload guidance without rollback or automatic retry. Binding-identity rereview then proved that two same-scope target copies with different sorted bound-agent sets were T4-ambiguous but incorrectly became T5
VerifiedorAlreadyVerified; the repair reuses the complete T4 copy identity for both mutation decisions and leaves both pathsUnverified. - files edited/created:
apps/cli/src/features/operator-skill/installed-state.ts;apps/cli/src/features/operator-skill/lifecycle-mutation.ts;apps/cli/src/features/operator-skill/lifecycle-mutation.test.ts;apps/wiki/content/docs/project/specs/cli/IP-322-operator-skill-state/PLAN.md;apps/wiki/content/docs/project/specs/cli/IP-322-operator-skill-state/IMPLEMENTATION-NOTES.md - backlog_item_id: IP-342
- backlog_item_url: https://linear.app/devpunks/issue/IP-342/verify-every-operator-mutation-and-preserve-truthful-partial-success
- relation_mode: native
- assigned_skills: [
autoreview,backend-recoverable-actions,codebase-design,effect-authoring,effect-backend-structure,effect-best-practices,effect-recoverable-actions,improve-codebase-architecture,parallel-research,quality-types,simplify,swarm-planner,tdd,turborepo] - tdd_status: required
- tdd_target: Current mutation booleans trust exit status, suppress global install when local exists, and cannot preserve typed partial success.
- red_command:
bun run --cwd apps/cli test -- src/features/operator-skill/lifecycle-mutation.test.ts -t 'install|update|partial|unverified' - expected_red_failure: The authored traces show local presence suppressing global installation or exit-zero updates counted as success without matching post-inspection; mixed scopes do not return the expected retained success, typed failure, exact retry, and reload guidance.
- green_command:
bun run --cwd apps/cli test -- src/features/operator-skill/lifecycle-mutation.test.ts && bun run --cwd apps/cli check-types - reason_not_testable:
- red_evidence: The exact RED command exited 1 because
./lifecycle-mutationdid not exist, proving no typed install/update mutation boundary implemented the authored local-only install, both-scope update, partial, retry, and unverified cases. Manual review then produced incremental REDs: 1/8 because a stalehi-clireported through typed identity-verification failure was classified as unknown and skipped; 1/9 because the intended target beside a competing active same-scope identity was incorrectly accepted as verified; 1/10 because install rewrote an already verified global target and emitted unnecessary reload guidance. Review repair then deleted source, version, revision, compatibility, active-agent, typed binding-failure selection, and scope-selection predicates one at a time; each named focused case exited 1, independently locking every predicate. Binding-identity REDs independently observed post-writeVerifiedand preflightAlreadyVerifiedeven though T4 returnedAmbiguousfor two global target copies whose sorted bound agents were[codex]and[claude,codex]. - green_evidence: The exact GREEN command exited 0 with lifecycle-mutation 17/17 and
tsc --noEmitclean. The complete operator-skill regression passed 70/70 across five files, focused lifecycle/operator passed 41/41, and the full CLI regression passed 296/296 across 34 files. Focused Oxfmt and tracked/untracked diff integrity passed. Targeted local autoreview returned no findings andpatch is correctwith confidence0.98. - codebase_design_notes: Mutation is an action ledger, not a transaction across independent scopes. Verification consumes the same T4 read model and its exported complete copy-identity serializer, keeping scope/root, target fields, compatibility, and sorted bindings singular. External scope writes run sequentially and independently. No cross-scope rollback or automatic retry is claimed; a retained typed action plus frozen target and copied input forms the explicit repair path for every failed or unverified scope. T6 alone owns removal.
- review_mode: cli
- runtime_validation: not_required
- runtime_target: not_applicable
- runtime_evidence: not_applicable
- runtime_cleanup: not_applicable
T6: Gate legacy removal on verified compatible replacement
- depends_on: [T5]
- location:
apps/cli/src/features/operator-skill/lifecycle.ts;apps/cli/src/features/operator-skill/lifecycle-migration.test.ts;apps/cli/src/features/operator-skill/test-fixtures/migration-cases.json - description: Implement IP-342 migration. Resolve every legacy fallback affected by project/global precedence, establish and verify compatible
hi-clireplacements first, then remove only eligibledp-clicopies and re-inspect. Refuse unsafe removal when any affected fallback lacks replacement. Preserve completed replacement/removal actions, report partial success, emit exact retry plus reload/reactivation guidance, and never mutate unrelated skills. - validation: Ordered traces prove replacement-before-removal, global fallback coverage, incompatible/missing/unverified refusal, remove failure, post-remove verification, partial success, exact recovery, and unrelated-copy preservation.
- status: Complete
- log: 2026-07-18 — Added a migration-specific Effect action ledger. It preflights applicable scopes, freezes affected legacy scopes in global then project-local order, and establishes an exact compatible same-scope
hi-clicopy for every affected scope before anydp-cliremoval. Any applicable preflight unknown or replacement failure/unverified result refuses all removals while retaining successful replacement writes and reload guidance. Chronological immediateReplacementVerifiedactions remain visible when the later final barrier fails; phase-distinctBarrierInspectionFailedorBarrierUnverifiedactions are appended. Final verified data separately preserves each exact replacement identity. After every remove attempt, including a typed adapterLeft, complete reinspection validates all current, prior, and pending affected barriers plus preserved unrelated-agent legacy identities. Lost pending barriers emit typedLegacyRemovalRefusedand skip removal; lost current/prior barriers append phase-specificRemovalBarrierLost, preserve the attempt fact, and close every remaining removal gate. Observable legacy change onLeftappends partial-change truth and reload guidance. Guarded retries freeze phase, affected scopes, and target; target drift is rejected, missing replacements are restored even when legacy disappeared, and only currently observed active legacy is removed. No rollback or automatic retry occurs. - files edited/created:
.agents/notes/index.md;.agents/notes/2026-07-18-operator-skill-migration-barriers.md;apps/cli/src/features/operator-skill/installed-state.ts;apps/cli/src/features/operator-skill/lifecycle-mutation.ts;apps/cli/src/features/operator-skill/lifecycle-migration.ts;apps/cli/src/features/operator-skill/lifecycle-migration.test.ts;apps/wiki/content/docs/project/specs/cli/IP-322-operator-skill-state/PLAN.md;apps/wiki/content/docs/project/specs/cli/IP-322-operator-skill-state/IMPLEMENTATION-NOTES.md - backlog_item_id: IP-342
- backlog_item_url: https://linear.app/devpunks/issue/IP-342/verify-every-operator-mutation-and-preserve-truthful-partial-success
- relation_mode: native
- assigned_skills: [
autoreview,backend-recoverable-actions,codebase-design,effect-authoring,effect-backend-structure,effect-best-practices,effect-recoverable-actions,improve-codebase-architecture,parallel-research,quality-types,simplify,swarm-planner,tdd,turborepo] - tdd_status: required
- tdd_target: Current migration can remove legacy scopes after an unverified global install and does not model affected fallbacks.
- red_command:
bun run --cwd apps/cli test -- src/features/operator-skill/lifecycle-migration.test.ts - expected_red_failure: The authored call-order assertions observe legacy removal before every affected fallback has a verified compatible replacement, or observe hidden partial removal instead of the expected refusal, retained success, exact retry, and reload guidance.
- green_command:
bun run --cwd apps/cli test -- src/features/operator-skill/lifecycle-migration.test.ts && bun run --cwd apps/cli check-types - reason_not_testable:
- red_evidence: The exact focused RED exited 1 because
./lifecycle-migrationdid not exist. After the initial matrix was authored, a deliberate barrier-predicate deletion made the named dual-scope case exit 1 because the result becameCompletedinstead ofRefused, independently proving that no removal may start when one replacement fails. Review then added four RED tracers: unrelated-agent legacy incorrectly triggered migration; an unrelated residual binding made active-agent removal unverified; final barrier inspection failure still removed; and final binding-distinct ambiguity still removed. All four failed together before repair. Final review added two outside-project REDs: global plus project legacy incorrectly produced four actions instead of global-only replacement/removal, while project-only legacy outside its root installed and removed instead of remaining idempotent. Structured autoreview then added three REDs: after global removal, a missing or uninspectable pending project replacement was still removed, and a current replacement whose binding identity changed was incorrectlyLegacyRemoved. Final rereview added two REDs proving that a global removeLeftcould still partially delete or binding-change the pending project replacement before project removal was attempted. Second structured autoreview added two REDs proving final barrier failure/ambiguity erased the preceding successful replacement-write action. Final structured autoreview added two REDs: failed global removal erased its current replacement without a barrier-loss fact or recoverable retry, and later project removal erased a prior successful global barrier without appending the loss. Closing structured review produced eight failing assertions covering remaining-gate closure after current loss onLeftandRight, unrelated-agent legacy loss, observed active-legacy change afterLeft, project failure applicability, and frozen retry-target drift. - green_evidence: Source-branch history: the migration matrix, wider operator suite, CLI build, and TypeScript gates passed before the manual convergence port. Current convergence totals are recorded in T9.
- codebase_design_notes: Migration owns the policy seam and returns one typed chronological action ledger; the adapter remains a mechanics-only port. T5 exports its singular exact scope verifier and ensure/reinspect action so migration cannot drift on source, version, revision, compatibility, scope/root, active binding, or sorted bound-agent competing identity. T4 exports its project-path applicability predicate, reused for preflight, final barrier, and affected-scope filtering. Preflight and replacement barriers are atomic refusal gates. Immediate outcomes remain immutable ledger facts. Final verified results build separate replacement and unrelated-legacy identity snapshots. One barrier helper consumes every complete post-attempt inspection for both
Leftand successful remove results, skips invalid pending snapshots, appends current/prior loss without rewriting attempt outcomes, and closes remaining gates. Guarded retry re-enters full policy with frozen recovery context and rejects target drift; ordinary migration remains no-legacy idempotent. Successful peers remain changed, no rollback is claimed, and no retry exposes naked remove. - review_mode: cli
- runtime_validation: not_required
- runtime_target: not_applicable
- runtime_evidence: not_applicable
- runtime_cleanup: not_applicable
T7: Cut the operator commands over to the typed lifecycle
- depends_on: [T6]
- location:
apps/cli/src/cli/operator-command.ts;apps/cli/src/cli/operator-command.test.ts;apps/cli/src/cli/skills-command.ts;apps/cli/src/cli/skills-command.test.ts;apps/cli/src/integrations/cli-maintenance.ts;apps/cli/src/integrations/cli-maintenance.test.ts;apps/cli/src/cli/public-output-contract.test.ts;apps/cli/test-fixtures/public-output/operator-*.json;apps/cli/test-fixtures/public-output/command-modes.json;apps/cli/src/features/operator-skill/application.ts; apps/cli/src/features/operator-skill/port.ts; apps/cli/src/platform/feature-application-operations.ts; apps/cli/src/runtime/config.ts - description: Wire
status|install|update|migrateto the feature Layer and presentation-neutral result. Public output reports immutable target and installed identities, effective/shadowed copies, compatibility, every per-scope success/failure/unverified action, exact retry, and reload guidance. Expected adapter/lifecycle failures exit nonzero without false absence. Keephi skills renameas the already-characterized thin deprecated delegate only. Remove operator types, parsing, commands, and policy fromintegrations/cli-maintenance.ts; leave executable self-update behavior intact. - validation: Focused command tests plus packaged subprocess fixtures cover status, local-over-global, missing/broken Skills CLI, verified success, mixed partial success, unsafe migration refusal, stdout/stderr/exit behavior, and unchanged deprecated delegation. Import/search guards prove commands and self-update no longer own Skills CLI mechanics.
- status: Complete
- log: Replaced the boolean/core operator path with the typed feature lifecycle and one live runtime Layer. Commands expose immutable/effective/shadowed state, typed failure, verified per-scope ledgers, guarded frozen retries, and reload guidance. The deprecated rename alias only delegates. Operator mechanics/policy left executable self-update. Iterative review repaired active-agent detection/normalization, markerless project scope, safe retry re-entry, invalid token handling, absent update semantics, packaged success/mixed coverage, and stream capture.
- files edited/created:
apps/cli/src/cli/operator-command.ts;apps/cli/src/cli/operator-command.test.ts;apps/cli/src/cli/skills-command.ts;apps/cli/src/cli/skills-command.test.ts;apps/cli/src/cli/public-output-contract.test.ts;apps/cli/src/integrations/cli-maintenance.ts;apps/cli/src/integrations/cli-maintenance.test.ts;apps/cli/src/features/operator-skill/application.ts; apps/cli/src/features/operator-skill/port.ts; apps/cli/src/platform/feature-application-operations.ts; apps/cli/src/runtime/config.ts;apps/cli/src/index.ts;apps/cli/test-fixtures/public-output/operator-*.json;apps/cli/test-fixtures/public-output/command-modes.json - backlog_item_id: IP-322
- backlog_item_url: https://linear.app/devpunks/issue/IP-322/make-operator-skill-state-immutable-and-verifiable
- relation_mode: native
- assigned_skills: [
autoreview,codebase-design,effect-authoring,effect-backend-structure,effect-best-practices,effect-recoverable-actions,improve-codebase-architecture,parallel-research,quality-types,simplify,swarm-planner,tdd,turborepo] - tdd_status: required
- tdd_target: Packaged commands cannot expose immutable/effective/partial state and currently infer failures from booleans.
- red_command:
bun run --cwd apps/cli build && bun run --cwd apps/cli test -- src/cli/operator-command.test.ts src/cli/public-output-contract.test.ts -t 'operator' - expected_red_failure: Public operator output lacks target identity, compatibility, effective/shadowed copies, typed failures, verified partial outcomes, and exact recovery.
- green_command:
bun run --cwd apps/cli test -- src/features/operator-skill src/cli/operator-command.test.ts src/cli/skills-command.test.ts && bun run --cwd apps/cli build && bun run --cwd apps/cli check-types && bun run --cwd apps/cli test -- src/cli/public-output-contract.test.ts && ! rg -n 'spawnSync|parseSkillList|skillInstallCommand|skillUpdateCommand|legacySkillRemoveCommand|manageHiCliSkill' apps/cli/src/cli apps/cli/src/integrations/cli-maintenance.ts - reason_not_testable:
- red_evidence: The exact planned RED exited 1 because missing Skills CLI output claimed every copy was not installed instead of reporting typed detection failure; the old command seam still collapsed failure into false absence.
- green_evidence: Current convergence GREEN passed focused operator, integration, and command suites 133/133, public-output and brand suites 15/15, CLI build, TypeScript, the forbidden-mechanics search guard, and
git diff --check. Final review repaired generic initial global inspection failure: install now returns a failed inspection action with a guarded inspection retry, performs zero writes, and keeps reloadNotRequired; typed identity or binding evidence can still select repair. Project-scoped Skills CLI list/install/remove now use the detected project root, while global operations retain invocation cwd; nested-monorepo coverage proves the split. Mutation retries reauthorize the current scope: generic unknown state performs no write with reloadNotRequired, absent update returns a typed invalid retry, observed identity/binding update and known global install remain repairable, and project install retry is rejected. The live Skills CLI preservesdp-clicopies bound only to an unrelated agent so the domain can filter them, while active-agent binding failure remains enforced forhi-cli. The packaged matrix covers unavailable/broken tooling, shadowing, verified success, mixed and absent update, safe migration/refusal, guarded retry boundaries, active-agent context, streams/exits, and deprecated delegation. - codebase_design_notes: Runtime composition supplies the live adapter once. Commands translate typed outcomes to the shared result contract; the deprecated alias delegates without owning policy. No compatibility shim or dual lifecycle remains.
- review_mode: cli
- runtime_validation: required
- runtime_target: Packaged
hiandhintagainst a run-owned fake Skills CLI and temporary project, across outside-project and inside-project cwd. - runtime_evidence: Run-owned fake Skills CLI validation exercised packaged
hiandhintinside and outside a temporary project. Traces proved immutable source/agent/scope arguments, post-write inspection, effective project-local plus shadowed global state, global fallback, verified install, mixed verified/failed update, replacement-before-removal migration, guarded retry/reload output, exact exits/streams, and cleanup with no remaining root or process. - runtime_cleanup: Use unique OS-temp roots and PATH; terminate fake adapter processes; remove only run-owned project/global fixtures; assert no temp roots or matching processes remain.
T8: Ingest operator-skill lifecycle documentation
- depends_on: [T7]
- location:
docs/README.md;docs/runbooks/hi-cli-scaffolding.md;apps/wiki/content/docs/cli/commands/operator.mdx;apps/wiki/content/docs/cli/commands/meta.json;apps/wiki/content/docs/cli/product-foundation/operator-skill-state.mdx;apps/wiki/content/docs/cli/product-foundation/meta.json;apps/wiki/content/docs/project/specs/cli/IP-322-operator-skill-state/IMPLEMENTATION-NOTES.md;apps/wiki/content/docs/project/specs/cli/IP-322-operator-skill-state/PLAN.md;apps/wiki/content/docs/project/specs/cli/IP-322-operator-skill-state/PHASE-HANDOFF.md;apps/wiki/content/docs/project/index.mdx;apps/wiki/index.md;apps/wiki/log.md - description: Run
docs-ingest-phaseafter behavior is proven. Document immutable identity/compatibility, local-over-global effective state, shadowed copies, verified per-scope mutation, partial success, exact recovery, reload guidance, and typed Skills CLI failures. Explicitly keep operator lifecycle separate from scaffold, baseline, packs, executable upgrade, shared-skill synchronization, and deprecated-alias redesign. Update wiki routing/bookkeeping and implementation evidence. - validation: Root runbook and routed pages agree with packaged behavior; links/navigation resolve; docs do not tell operators to install from moving
main; ingest bookkeeping records all IP-340/IP-341/IP-342 evidence. - status: Complete
- log: Private/internal ingest updated root docs, the mirrored runbook, spec evidence, project bookkeeping, and bare-command guide. Public artifact mode then preserved fragments, beats, and shape without pausing, as explicitly directed, and published a concise operator command flow plus an operator-skill-state concept. Moving-branch guidance is absent; lifecycle boundaries remain explicit.
- files edited/created:
docs/README.md;docs/runbooks/hi-cli-scaffolding.md;apps/wiki/content/docs/project/runbooks/hi-cli-scaffolding.md;apps/wiki/content/docs/project/specs/cli/IP-322-operator-skill-state/{SPEC.md,PLAN.md,IMPLEMENTATION-NOTES.md,PHASE-HANDOFF.md,meta.json};apps/wiki/content/docs/project/{index.mdx,public-docs/meta.json,public-docs/index.mdx,public-docs/operator-skill-state/{fragments.md,beats.md,shape.md,meta.json}};apps/wiki/content/docs/cli/commands/{operator.mdx,meta.json};apps/wiki/content/docs/cli/product-foundation/{operator-skill-state.mdx,meta.json};apps/wiki/index.md;apps/wiki/log.md;apps/cli/src/ui/brand.ts;apps/cli/src/ui/brand.test.ts - backlog_item_id: IP-322
- backlog_item_url: https://linear.app/devpunks/issue/IP-322/make-operator-skill-state-immutable-and-verifiable
- relation_mode: native
- assigned_skills: [
docs-ingest-phase,docs-onboarding,writing-beats,writing-fragments,writing-great-skills,writing-shape,agent-browser,async-react-patterns,autoreview,codebase-design,design-taste-frontend,frontend-domain-structure,improve-codebase-architecture,next-best-practices,next-cache-components,parallel-research,quality-types,react-doctor,simplify,tdd,technical-writing,turborepo,vercel-composition-patterns,vercel-react-best-practices] - tdd_status: not_applicable
- tdd_target: Documentation and durable evidence for already-tested behavior.
- red_command: not_applicable
- expected_red_failure: not_applicable
- green_command:
test "$(git diff --name-only --diff-filter=D | wc -l | tr -d ' ')" = 0 && bunx oxfmt --check docs/README.md docs/runbooks/hi-cli-scaffolding.md apps/cli/src/ui/brand.ts apps/cli/src/ui/brand.test.ts apps/wiki/content/docs/project/runbooks/hi-cli-scaffolding.md apps/wiki/content/docs/project/public-docs/operator-skill-state apps/wiki/content/docs/project/public-docs/meta.json apps/wiki/content/docs/project/public-docs/index.mdx apps/wiki/content/docs/cli/commands/operator.mdx apps/wiki/content/docs/cli/commands/meta.json apps/wiki/content/docs/cli/product-foundation/operator-skill-state.mdx apps/wiki/content/docs/cli/product-foundation/meta.json apps/wiki/content/docs/project/specs/cli/IP-322-operator-skill-state apps/wiki/content/docs/project/index.mdx apps/wiki/index.md apps/wiki/log.md && bun run --cwd apps/cli build && bun run --cwd apps/cli test -- src/ui/brand.test.ts src/cli/public-output-contract.test.ts && bun run --cwd apps/wiki test && bunx tsc --noEmit -p apps/wiki/tsconfig.json && test "$(git diff --name-only --diff-filter=D | wc -l | tr -d ' ')" = 0 && git diff --check - reason_not_testable: Docs-ingest task; behavioral RED/GREEN is owned by T1-T7.
- red_evidence:
- green_evidence: Private/internal gate passed: focused CLI build plus brand/public-output tests 10/10; wiki tests 6/6; direct non-mutating wiki TypeScript check; targeted Oxfmt check across 13 files; byte-identical root/private runbook bodies; moving-source command guard; routed IP-322 artifact existence; and
git diff --check. Public gate passed CLI build plus brand/public-output 10/10, wiki tests 6/6, direct TypeScript, targeted Oxfmt, exact route/meta/file assertions, moving-source guard, deletion guard0 -> 0, andgit diff --check. Structured review found and repaired inspection-retry overstatement plus the unsafe stale GREEN command; rereview returned no findings,patch is correct, confidence0.94. The scripted wikicheck-typesreached a clean type result during the private pass but its preceding write-mode content sync pruned 168 unrelated routed files; all 168 status-D paths were verified, restored from HEAD, and the five IP-322 edits were reapplied. That destructive wrapper was not rerun. - codebase_design_notes: Docs explain one lifecycle and its boundaries. No source-repository sync, baseline release, skill rename, or scaffold follow-through instructions are added.
- review_mode: cli
- runtime_validation: not_required
- runtime_target: not_applicable
- runtime_evidence: not_applicable
- runtime_cleanup: not_applicable
T9: Run final operator lifecycle, review, and consumer gates
- depends_on: [T8]
- location: Read-only validation of
apps/cli/src/features/operator-skill/target.test.ts;apps/cli/src/features/operator-skill/installed-state.test.ts;apps/cli/src/integrations/skills-cli.test.ts;apps/cli/src/features/operator-skill/lifecycle-status.test.ts;apps/cli/src/features/operator-skill/lifecycle-mutation.test.ts;apps/cli/src/features/operator-skill/lifecycle-migration.test.ts;apps/cli/src/cli/operator-command.test.ts;apps/cli/src/cli/skills-command.test.ts;apps/cli/src/cli/public-output-contract.test.ts;docs/README.md;docs/runbooks/hi-cli-scaffolding.md;apps/wiki/content/docs/cli/commands/operator.mdx;apps/wiki/content/docs/cli/product-foundation/operator-skill-state.mdx; no owned write paths - description: Parent performs a strictly read-only rerun of focused lifecycle/adapter/command tests, packaged
hi/hintpublic seams, a representative run-owned consumer, docs checks, and the comprehensive repository suite. Run findings-first review plus structured autoreview against the actual parent base. Reject moving refs, false absence, project-local suppression of global default, unverified success, unsafe legacy removal, hidden partial results, direct subprocess mechanics outside the adapter, filesystem fallback, dual lifecycle, or cross-scope work. Do not repair findings in T9; route each finding to the owning T1-T8 worker and rerun T9 only after that task is green. - validation: Every IP-340/IP-341/IP-342 criterion has durable current evidence; integration state remains parent-owned and was not rerun in this slice.
- status: Complete
- log: Manual convergence validation passed focused operator, integration, and command suites 133/133 plus public-output and brand suites 15/15, for 148/148 focused tests. Mutation and migration passed 66/66. CLI build and typecheck passed; the build emitted 526 modules. Effect validators passed 93/93 with 1,352 expectations. Full CLI passed 626/626 across 56 files, and the corrected diff plus untracked set passed lint across 48 TypeScript files.
- files edited/created:
apps/wiki/content/docs/project/specs/cli/IP-322-operator-skill-state/{PLAN.md,IMPLEMENTATION-NOTES.md,PHASE-HANDOFF.md};apps/wiki/index.md;apps/wiki/log.md - backlog_item_id: IP-322
- backlog_item_url: https://linear.app/devpunks/issue/IP-322/make-operator-skill-state-immutable-and-verifiable
- relation_mode: native
- assigned_skills: [
review-phase,autoreview,codebase-design,effect-authoring,effect-best-practices,effect-recoverable-actions,quality-types,simplify,tdd,turborepo] - tdd_status: not_applicable
- tdd_target: Aggregate acceptance/review over already test-driven vertical slices.
- red_command: not_applicable
- expected_red_failure: not_applicable
- green_command:
test "$(git diff --name-only --diff-filter=D | wc -l | tr -d ' ')" = 0 && bun run --cwd apps/cli test && bun run --cwd apps/cli build && bun run --cwd apps/cli check-types && bun run --cwd apps/wiki test && bunx tsc --noEmit -p apps/wiki/tsconfig.json && bun run test && test "$(git diff --name-only --diff-filter=D | wc -l | tr -d ' ')" = 0 && git diff --check - reason_not_testable: Review/aggregate gate; behavioral RED/GREEN belongs to T1-T7.
- red_evidence:
- green_evidence: Current convergence evidence: operator, integration, and command suites 133/133; public-output and brand suites 15/15; 148/148 focused total; mutation and migration 66/66; CLI build and typecheck PASS; Effect architecture validators 93/93 with 1,352 expectations; full CLI 626/626 across 56 files; build 526 modules; corrected diff plus untracked lint 48 TypeScript files GREEN. Final review proved generic initial global inspection failure blocks install, returns a failed inspection action with a guarded inspection retry, performs zero writes, and keeps reload
NotRequired; typed identity or binding evidence may still select repair. Project-scoped Skills CLI operations use detected project root while global operations retain invocation cwd, including nested-monorepo coverage. Mutation retries reauthorize current scope: generic unknown is no-write/NotRequired, absent update is typed invalid, observed identity/binding update and known global install remain repairable, and project install retry is rejected. Live Skills CLI preserves unrelated-agent-onlydp-clievidence for domain filtering and still enforces active-agent binding forhi-cli. - codebase_design_notes: Apply the deletion test: removing the lifecycle or adapter must force policy or mechanics into multiple callers. Confirm executable self-update remains separate and no operator behavior leaks into scaffold/baseline/pack domains.
- review_mode: mixed
- runtime_validation: required
- runtime_target: Packaged
hi/hint, run-owned fake Skills CLI, and one run-owned representative consumer repository. - runtime_evidence: Current focused tests prove immutable identity and compatibility, inside/outside-project precedence,
.git-only project context, active-agent binding, shadowed copies, typed detection failure, verified full/partial mutation, safe migration order, exact retries, and pure canonical-path containment. - runtime_cleanup: Use unique run ids and OS-temp roots; terminate fake Skills CLI/consumer processes; remove only run-owned roots; prove no matching process, temporary skill home, or consumer root remains.
Testing Strategy
- Start with public semantic REDs, then implement the narrow feature seam. T1 and T2 remain independent until T3.
- Test target and precedence policy as pure functions. Test external mechanics only through the adapter contract and deterministic process fixtures.
- Assert installed identity as source plus exact version plus immutable revision plus compatibility, never name/path presence alone.
- For every write test, require a post-write inspection event before success. Include successful exit with mismatched observed state.
- Model per-scope action ledgers. Mixed success must retain successes, failures, exact retries, and reload guidance.
- Test packaged commands for stdout, stderr, exit status, inside/outside cwd, active agent, and no false absence.
- Never invoke or mutate the real global Skills CLI state in automated/runtime validation.
Review and Evidence Gates
- Plan gate: parent
plan-reviewerchecks IP-340/IP-341 roots, IP-342 convergence, exact paths, public REDs, and parent-base intent. - Read roots gate T4: immutable compatible target and effective/shadowed installed state pass before any lifecycle mutation.
- Mutation gate T6: every success is observed; partial results and safe replacement/removal are proven.
- Public gate T7: packaged operator commands expose truthful results; old core policy/mechanics are deleted; alias remains only a delegate.
- Docs gate T8: runbook, routed pages, navigation, and implementation evidence match proven behavior.
- Final gate T9: focused, packaged, consumer, comprehensive, cleanup, review, and exact PR-base checks pass.
Risks and Mitigations
| Risk | Mitigation |
|---|---|
| Compatibility metadata follows a moving ref | T1 rejects branch-only identity and byte-locks exact source/version/revision. |
| Listing failure becomes absence | Typed adapter errors plus T2/T4 failure fixtures. |
| Local copy suppresses global default | T5 public RED begins with local-only state and requires verified global creation. |
| Exit zero is accepted without correct state | Every mutation trace requires re-inspection and exact identity/binding match. |
| Partial failure triggers rollback or hides success | Per-scope ledger and mixed-outcome fixtures preserve independent successes. |
| Legacy removal breaks fallback | T6 computes affected fallback coverage and orders verified replacement first. |
| Mechanics leak into domain/commands | One adapter plus import/search guards in T3/T7/T9. |
| Tests mutate developer skill homes | Fake executable, injected Layers, unique temp roots, and explicit cleanup proof. |
| Scope expands into shared skills/baseline/rename | Locked exclusions, exact task paths, and final diff review. |
Backlog Sync
- IP-322 is the epic; IP-340, IP-341, and IP-342 are the complete child story set.
- Native order is correct: IP-340 and IP-341 independently block IP-342.
- IP-330 is the completed upstream characterization gate.
- Planning creates no new items and performs no Linear mutation.
- Implementation closeout may update IP-340/IP-341 only after T4, IP-342 after T7, and IP-322 after T9.
Unresolved Questions
None. Exact internal symbols, compatibility encoding, immutable release/commit selection, and future explicit scope flags remain bounded implementation tuning and do not change the accepted lifecycle contract.
Stop Condition
Do not edit or synchronize the shared skill repository, publish a baseline, redesign rename behavior, commit, push, open a pull request, merge, deploy, or mutate backlog state from this coordinated delivery run.