Skip to content

S2: plan-exit posture switching + the posture indicator, one-click confirm (#859) - #864

Merged
aarontrowbridge merged 3 commits into
mainfrom
859-posture-switching
Sep 7, 2026
Merged

S2: plan-exit posture switching + the posture indicator, one-click confirm (#859)#864
aarontrowbridge merged 3 commits into
mainfrom
859-posture-switching

Conversation

@aarontrowbridge

@aarontrowbridge aarontrowbridge commented Sep 7, 2026

Copy link
Copy Markdown
Member

What

Implements S2 of spec-20260907-011500 (rev 2, D2): the plan's terminal artifact emits a structured posture_recommendation, and the posture indicator renders it as a one-click confirm surface with the full negative path — the fork #297 slice-b intent, ported to the app-overlay substrate (composed on the existing /amicode/* route family and the app's agent binding; no new engine contract).

The recommendation — artifact shape, never keywords (a0e50f58)

amico plan compile stamps posture_recommendation on the compiled plan (schema-declared additive field, the plan note's human echo rendered FROM the stamp, the CompileSuccess, and the verb JSON; plan_hash unchanged). The derivation is pure over the steps' task_types + the spec's optional agent executor hint:

  • implementation-shaped (implement-slice, author-script, bookkeeping) → develop; experiment-shaped (experiment-sim, experiment-hw, insight) → research
  • MIXED shape → ambiguous with BOTH modes named — no silent coin-flip
  • a determinable spec executor outranks the shape (read-resolve alias honored); unresolvable → ask; plan/build bind no executor posture
  • abandoned plan (no steps, or only administrative ones) → none: the offer never fires, and no executor hint rescues it

The posture indicator + the switching mechanics (bb143e0f)

  • GET/POST /amicode/posture (+ /dismiss): a DUMB READER of the stamped field — the service never re-derives; an unstamped plan reads null and the offer stays quiet. plan.auto_switch = confirm | auto (default confirm) rides the ops-dir prefs file, fail-safe to confirm; dismissal is per-plan_hash (a recompile re-arms the offer).
  • The indicator view-model (pure, headless-tested; the The native merged sessions view — Slice C of the local-shell data plane (amicissimo#393) #848/Extension sessions stage SKILL.md only — companion files dead-link; plus three skill-text fixes #393 pattern): named states absent/quiet/offer; the confirm surface carries the NEGATIVE path one click each — confirm / dismiss / wrong—actually <other mode> / stay in plan; mixed-shape names both modes as buttons; dismissed → ambient again.
  • Switch = the Tab-switch contract, made product: local.agent.set IS the mid-session re-bind; in-session it also lands the posture change on the session record (session.update metadata — the ADR-0011 vNext additive surface, fire-and-forget). auto defers the click to the TURN BOUNDARY (never mid-generation), announces, drops when a newer plan supersedes; ONLY the agent binding changes — the session's draft and pending questions ride along untouched.
  • Bidirectional (D2): in develop/research the collapsed indicator carries the walk-back-to-plan affordance.
  • Ambient-when-ignored (the observability clause): quiet until there is a recommendation; renders NOTHING when the route does not exist.
  • Mounted twice: the home flyout (default/draft posture) and the session header's titlebar-right portal (the mid-session surface).
  • i18n ×18 locales (15 keys, parity-checked); manifest hash registration for all 23 touched overlay files — the drift gate PASSES.

The boot proof (73b95f65)

The three routes answer on the REAL service (in-process boot): GET shape, the pref write round-tripping through the ops-dir file, the per-plan dismissal, the fixed bad_request on an off-vocabulary value.

Verification

  • pnpm -r run typecheck — green (schema ✓ amico-run ✓ extension ✓)
  • New tests: 16 (amico-run tie-breaks + stamp) + 14 (service + served wiring) + 19 (view-model + switch mechanics) — all green
  • Pre-existing failures (confirmed on clean main, env-dependent): agent_spawn.test.ts ×1 (amico-run, $AMICO_AGENT_CONFIG_DIR), terminal.test.ts ×2 (extension). editable_diffs ×2 and cli_gate are the chore(test): overlay-sync test applies to the local fork checkout's committed tree — point it at a temp tree #842 hazard's working-tree dirt / unstaged bins — both pass on a clean tree.
  • Overlay typecheck in a materialized v1.18.29 tree: the posture files are clean; 22 pre-existing errors exist in files this PR does not touch (stale sibling dists — CI does not typecheck the overlay).
  • CI: app-bundle-gate ✓, bundle-build-gate ✓, app-shelf-boot-proof ✓ (the rest ran at push time)

Refs #859

…dation — shape-derived, tie-breaks per spec D2

S2 (spec-20260907-011500 D2, #859): `amico plan compile` now stamps a
structured `posture_recommendation` on the compiled plan — data on the
artifact, the doctrine-clean crossing (the indicator reads it, never
re-derives, never keyword-guesses). The derivation is pure over the plan's
ARTIFACT SHAPE (the steps' task_types) plus the spec frontmatter's optional
`agent` executor hint:

- implementation-shaped (implement-slice, author-script, bookkeeping) → develop
- experiment-shaped (experiment-sim, experiment-hw, insight) → research
- MIXED shape → ambiguous, BOTH modes named — no silent coin-flip
- a determinable spec executor outranks the shape (read-resolve alias
  honored); unresolvable → ambiguous; plan/build bind no executor posture
- an abandoned plan (no steps, or only administrative ones) → kind 'none' —
  the offer never fires, and no executor hint rescues it

The stamp rides the plan frontmatter (schema-declared, additive), the plan
note's human-readable echo (rendered FROM the stamp, never re-derived), the
CompileSuccess result, and the plan-compile verb JSON. plan_hash is
unchanged — the recommendation is derived after hashing, so a recompile that
changed nothing still mints no new hash.

Refs #859
@coderabbitai

coderabbitai Bot commented Sep 7, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…gative path, mid-session re-bind, turn-boundary auto

S2 (spec-20260907-011500 D2, #859): the plan-exit confirm surface, first-
class on the app overlay (the fork #297 slice-b intent, ported to the
substrate — composed on the EXISTING /amicode/* route family and the app's
agent binding, never a new engine contract).

- GET/POST /amicode/posture (+ /dismiss): a DUMB READER of the compiled
  plan's STAMPED posture_recommendation — the service never re-derives,
  never keyword-guesses; an unstamped plan reads null and the offer stays
  quiet. plan.auto_switch = confirm | auto rides the ops-dir prefs file
  (fail-safe to confirm). Dismissal is per-plan_hash (a recompile re-arms).
- The indicator view-model (pure, headless-tested): named states absent /
  quiet / offer; the confirm surface carries the NEGATIVE path one click
  each — confirm / dismiss / wrong—actually <other mode> / stay in plan;
  a MIXED-shape recommendation names BOTH modes (the user picks — no
  silent coin-flip); dismissed → ambient again.
- Switch mechanics (the Tab-switch contract, made product):
  local.agent.set IS the mid-session re-bind; in-session it also lands the
  posture change on the session record (session.update metadata — the
  ADR-0011 vNext additive surface, fire-and-forget). plan.auto_switch=auto
  defers the click to the TURN BOUNDARY (never mid-generation), announces,
  drops when a newer plan supersedes; ONLY the agent binding changes — the
  session's draft and pending questions ride along untouched.
- Bidirectional (D2): the collapsed indicator in develop/research carries
  the walk-back-to-plan affordance.
- Ambient-when-ignored (the observability clause): quiet until there is a
  recommendation; the offer banner is the one thing that asserts itself;
  renders NOTHING when the route does not exist (older extension).
- Mounted twice: home flyout (acts on the default/draft posture) and the
  session header's titlebar-right portal (the mid-session re-bind surface).
- i18n ×18 locales (15 keys, parity-checked); manifest hash registration
  for all 23 touched overlay files (#848 gate — drift gate PASS).

Refs #859
The three routes answer on the REAL service (createAmicodeService booted
in-process): the GET shape, the auto_switch pref write round-tripping
through the ops-dir prefs file, the per-plan dismissal, and the fixed
bad_request on an off-vocabulary value.

Refs #859
@aarontrowbridge
aarontrowbridge marked this pull request as ready for review September 7, 2026 02:51
@aarontrowbridge
aarontrowbridge merged commit 65734c1 into main Sep 7, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant