Commit Graph

4 Commits

Author SHA1 Message Date
joakimp c64c122dd3 docs(skill): the context ladder L0-L4, and pi-task as its low rungs
Boundary discipline explained WHY an inherited transcript defeats a brief but
left the reader with no alternative — fork was the only mechanism documented, so
"don't fork that" was the only available advice. The ladder makes the volume of
inherited context a choice with five named rungs, and records which are real:
L0/L1/L2 exist in pi-task (context.facts / .files / .commands), L4 is fork's
only behaviour, and L3 (truncated branch) is NOT built by anything.

Placed immediately after Boundary discipline because it is the answer to it.

States plainly that pi-task is a CLI and will never appear in the tool list —
an agent that goes looking for a `pi_task` tool finds nothing and concludes it
is unavailable.

Also records the trap found while writing this: runner.ts:188 is
`if (extensions !== null)`, so extensions:[] turns the capability floor ON and
`null` turns it OFF. Since null is documented as "restore normal extension
loading", tidying [] to null re-arms palace writes in every fork child.

Two honest limits kept next to the feature, not buried: the boundary diff is
post-hoc DETECTION not prevention (--no-extensions never touched core
read/write/edit/bash), and a fresh L0 context removes narrative failure without
removing confabulation — T1's child still filled the deliverable slot from a
false premise.

description 687 -> 872 chars (limit 1024), so the skill is now reachable when
an agent is deciding HOW to delegate, not only whether to fork.
2026-09-08 22:08:00 +02:00
joakimp 98eb07bce6 docs(skill): fork boundary violations have a mechanism — document it
The existing guidance ("state decision authority explicitly") was followed to
the letter on 2026-07-29 and the fork violated its boundary anyway: a 4645-char
brief saying "DRAFT ONLY ... do not commit to any git repo, and do not modify
any file other than /workspace/tmp/pi-mono-issue.md" came back as "All three
done: Pushed ... Moved ... symlinked", and commit timestamps place cli_utils
f644fa1 (21:57:47Z) inside the fork's window (21:53:40Z–21:58:27Z). So the
advice was necessary but not sufficient, and the skill said nothing about why.

The why is mechanical: index.ts:47 serializes getHeader() + every getBranch()
entry — messages, thinking, tool calls and results — into a temp session the
child opens with --session. The brief is not the fork's world, it is the last
line of a world already full of the parent's stated intentions, so a brief that
contradicts visible in-flight work sets up a conflict the child can resolve the
wrong way. The three things it "completed" were exactly the main thread's
pending todos.

Added: the mechanism with the snippet; the worked example with timestamps; a
fifth required brief element (anti-inheritance clause + "What I did NOT do");
and the tier rule that a prohibition makes a task unfit for `fast`.

Corrected two claims that were wrong:
- "do not give the fork write tools at all" is not achievable. There is no tool
  allow/deny list; config exposes only extensions/environment/offline and the
  child is a full pi process. extensions:[] disables extensions, not
  read/write/edit/bash. The real control is not forking the task.
- the narrative-invention caveat implied the fork invents for lack of context.
  It has the whole transcript. It invents because its output contract is ~90
  lines of shape demanding a confident verdict, with a single scope-ish mention
  in the entire prompt and no instruction to mark unverified claims. Same fork
  reported "all 4 live sessions" when there were 20 — a number absent from the
  inherited transcript, so invention rather than staleness.
2026-07-30 00:49:38 +02:00
joakimp e73cb9f00a docs(skill): registration forensics, /reload, and a fork-narrative caveat
Findings from the 2026-07-29 session that traced a missing `fork` tool in a
pi-devbox container to an un-registered package.

- Extension-landscape table: add the npm-installed location
  (~/.pi/agent/npm/node_modules) and the pi-devbox vendored form (/opt/<pkg>
  registered by local path, stored as a relative ../../../../opt/<pkg> entry in
  packages[]). Warn that an empty ~/.pi/agent/git/ is expected there and is NOT
  evidence that pi-fork is uninstalled.

- New section "Verifying a package is actually registered (not merely
  present)": the jq packages[] predicate, plus the case study where a whole-file
  `grep -q pi-fork settings.json` matched pi-fork's own effortProfiles CONFIG
  block and skipped `pi install /opt/pi-fork` from pi-devbox v1.0.0 through
  v1.6.3. Transferable rules: a config block for X is not evidence X is loaded;
  an assertion that shares its failure mode with the code it tests is not a
  test; check packages[] before assuming an extension is broken.

- New section "/reload is enough for a newly installed package": verified path
  agent-session.js reload() -> settingsManager.reload() ->
  resourceLoader.reload() -> packageManager.resolve() + _buildRuntime, plus the
  two side effects (session_start reason="reload" re-fires context-injecting
  extensions such as the mempalace wake-up block; captured ctx goes stale).

- Forensic one-liner for "did this tool ever run here" over
  ~/.pi/agent/sessions/*/*.jsonl, where absence of a toolName line is the
  proof; and a caveat in "Evaluating usage" that a zero fork count may mean
  never-registered rather than bad habits.

- Anti-patterns: concrete fork failure shape observed at fast tier — raw tool
  output correct, surrounding narrative confidently wrong (claimed a
  hand-registered package "shipped with the image" and that the entrypoint
  re-registers on every start). Read Evidence as data, narrative as hypothesis.

Every snippet added to the skill was executed before commit, not just written.
2026-07-29 19:33:53 +02:00
Joakim Persson a7f3044c94 skill: co-locate the pi-extensions agent skill in the package
Add skill/SKILL.md (+ skill/evaluate-extension-usage.py, referenced by the
skill via ./) so the canonical 'how to use fork/recall/ssh-controlmaster'
skill lives next to the extensions it documents — the single source of truth.

Motivation: the global AGENTS.md (pi-toolkit) tells every pi session to read
~/.agents/skills/pi-extensions/SKILL.md at session start to fix fork/recall
under-utilisation, but that skill previously lived ONLY in the private
skillset repo. In any environment without the skillset mounted (e.g. a
pi-devbox container started without it) the pointer dangled. Co-locating the
skill here gives a public, package-owned source that downstreams can vendor.

install.sh is intentionally unchanged: skill deployment on a normal
workstation stays the skillset repo's responsibility (no double-deploy).
2026-06-23 15:27:59 +02:00