@akagilnc/pi-workflow-roles 0.1.5037 → 0.1.5066

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +2 -2
  2. package/README.zh-CN.md +2 -2
  3. package/THIRD_PARTY_NOTICES.md +11 -23
  4. package/dist/acp-host/production-host.js +410 -878
  5. package/dist/headless-host/description.js +0 -2
  6. package/dist/headless-host/production-host.js +413 -914
  7. package/dist/host-descriptions.js +2 -3
  8. package/dist/migrate-book-topology.js +4 -10
  9. package/dist/packaged-role-registry.js +17 -16
  10. package/dist/pi/role-turn-host.js +3 -27
  11. package/dist/public-cli/cli.js +6 -0
  12. package/dist/public-cli/instruction-seat-run.js +12 -40
  13. package/dist/public-cli/machine-method-skills.js +150 -0
  14. package/dist/public-cli/main.js +378 -579
  15. package/dist/public-cli/post-admission.js +2 -0
  16. package/dist/public-cli/registry.js +2 -1
  17. package/dist/public-cli/settlement.js +12 -99
  18. package/dist/public-cli/turn-request.js +16 -8
  19. package/package.json +3 -1
  20. package/resources/836-deleted-machine-instruction-inventory.md +1 -1
  21. package/scripts/build-package.mjs +1 -6
  22. package/src/headless-host/description.ts +0 -3
  23. package/src/headless-host/role-turn-host.ts +2 -23
  24. package/src/host-contracts.ts +2 -23
  25. package/src/host-descriptions.ts +2 -3
  26. package/src/packaged-role-registry.ts +14 -14
  27. package/src/pi/adapter.ts +0 -27
  28. package/src/pi/role-turn-host.ts +3 -31
  29. package/src/public-cli/cli.ts +6 -0
  30. package/src/public-cli/instruction-seat-run.ts +9 -42
  31. package/src/public-cli/machine-method-skills.ts +153 -0
  32. package/src/public-cli/post-admission.ts +2 -0
  33. package/src/public-cli/registry.ts +1 -0
  34. package/src/public-cli/settlement.ts +6 -138
  35. package/src/public-cli/turn-request.ts +24 -16
  36. package/src/reviewer-role.ts +1 -12
  37. package/src/role-envelope.ts +0 -13
  38. package/src/role-runtime-dependencies.ts +0 -13
  39. package/src/role-runtime.ts +4 -56
  40. package/src/worker-role.ts +1 -81
  41. package/dist/method-host-plugin/.claude-plugin/plugin.json +0 -5
  42. package/dist/method-host-plugin/skills/ak-cross-m-review/CONTEXT.md +0 -48
  43. package/dist/method-host-plugin/skills/ak-cross-m-review/LICENSE +0 -21
  44. package/dist/method-host-plugin/skills/ak-cross-m-review/SKILL.md +0 -170
  45. package/dist/method-host-plugin/skills/ak-cross-m-review/prompts/cmr-completeness.md +0 -118
  46. package/dist/method-host-plugin/skills/ak-cross-m-review/prompts/cmr-reviewer.md +0 -128
  47. package/dist/method-host-plugin/skills/ak-cross-m-review/provenance.json +0 -41
  48. package/dist/method-host-plugin/skills/diagnosing-bugs/SKILL.md +0 -134
  49. package/dist/method-host-plugin/skills/diagnosing-bugs/agents/openai.yaml +0 -3
  50. package/dist/method-host-plugin/skills/diagnosing-bugs/provenance.json +0 -31
  51. package/dist/method-host-plugin/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +0 -41
  52. package/dist/method-host-plugin/skills/resolving-merge-conflicts/SKILL.md +0 -14
  53. package/dist/method-host-plugin/skills/resolving-merge-conflicts/agents/openai.yaml +0 -3
  54. package/dist/method-host-plugin/skills/resolving-merge-conflicts/provenance.json +0 -26
  55. package/dist/method-host-plugin/skills/tdd/SKILL.md +0 -38
  56. package/dist/method-host-plugin/skills/tdd/agents/openai.yaml +0 -3
  57. package/dist/method-host-plugin/skills/tdd/mocking.md +0 -59
  58. package/dist/method-host-plugin/skills/tdd/provenance.json +0 -36
  59. package/dist/method-host-plugin/skills/tdd/tests.md +0 -77
  60. package/dist/package-resources/method-skill.js +0 -259
  61. package/resources/method-host-plugin/.claude-plugin/plugin.json +0 -5
  62. package/resources/methods/ak-cross-m-review/CONTEXT.md +0 -48
  63. package/resources/methods/ak-cross-m-review/LICENSE +0 -21
  64. package/resources/methods/ak-cross-m-review/SKILL.md +0 -170
  65. package/resources/methods/ak-cross-m-review/prompts/cmr-completeness.md +0 -118
  66. package/resources/methods/ak-cross-m-review/prompts/cmr-reviewer.md +0 -128
  67. package/resources/methods/ak-cross-m-review/provenance.json +0 -41
  68. package/resources/methods/diagnosing-bugs/SKILL.md +0 -134
  69. package/resources/methods/diagnosing-bugs/agents/openai.yaml +0 -3
  70. package/resources/methods/diagnosing-bugs/provenance.json +0 -31
  71. package/resources/methods/diagnosing-bugs/scripts/hitl-loop.template.sh +0 -41
  72. package/resources/methods/resolving-merge-conflicts/SKILL.md +0 -14
  73. package/resources/methods/resolving-merge-conflicts/agents/openai.yaml +0 -3
  74. package/resources/methods/resolving-merge-conflicts/provenance.json +0 -26
  75. package/resources/methods/tdd/SKILL.md +0 -38
  76. package/resources/methods/tdd/agents/openai.yaml +0 -3
  77. package/resources/methods/tdd/mocking.md +0 -59
  78. package/resources/methods/tdd/provenance.json +0 -36
  79. package/resources/methods/tdd/tests.md +0 -77
  80. package/src/canonical-skill-binding.ts +0 -118
  81. package/src/host-native-method.ts +0 -185
  82. package/src/package-resources/method-skill-binding.ts +0 -60
  83. package/src/package-resources/method-skill.ts +0 -363
@@ -863,6 +863,7 @@ export function resumeTurnRequestProjectionOptions(admitted, request, env, summo
863
863
  return {
864
864
  packageRoot: env.packageRoot,
865
865
  home: env.home,
866
+ ...(env.host === undefined ? {} : { host: env.host }),
866
867
  agentDir: env.agentDir,
867
868
  ...(env.model === undefined ? {} : { model: env.model }),
868
869
  ...pickEngineAxis(env),
@@ -884,6 +885,7 @@ export function roleTurnOptions(env, admitted, continuation) {
884
885
  return {
885
886
  packageRoot: env.packageRoot,
886
887
  home: env.home,
888
+ ...(env.host === undefined ? {} : { host: env.host }),
887
889
  agentDir: env.agentDir,
888
890
  ...(env.model === undefined ? {} : { model: env.model }),
889
891
  ...pickEngineAxis(env),
@@ -13,7 +13,8 @@ const PUBLIC_CLI_SUPPORT_COMMANDS = [
13
13
  "config",
14
14
  "help",
15
15
  "resume",
16
- "new"
16
+ "new",
17
+ "setup"
17
18
  ];
18
19
  function seatModelOnly(seat) {
19
20
  if (seat?.provider === void 0 || seat.model === void 0) return void 0;
@@ -28,7 +28,6 @@ import { DOCTOR_CANDIDATE_ENTRY_TYPE } from "../dossier-resolution.js";
28
28
  import { REVIEWER_OUTPUT_TOOL_NAME, } from "../package-contracts/reviewer-output.js";
29
29
  import { packagedAuditToolName, packagedDurableOfficerEntry, packagedProjectsTargetBindRejection, packagedRoleAcceptedOutputTool, packagedRoleMetadata, packagedSkipsGateOnInfrastructureStage, } from "../packaged-role-registry.js";
30
30
  import { SECRETARIAT_COUNTERSIGN_TERMINAL_FACT_KEY, SECRETARIAT_GATE_OFFICER_ENTRY_TYPE, } from "../secretariat-contracts.js";
31
- import { observePackagedMethodSkillInvocation, resolvePackagedMethodSkillPath, } from "../package-resources/method-skill.js";
32
31
  import { classifyPackagedRoleTerminalResult, findLatestDurablePackagedRoleTerminal, hasNavigatorInfrastructureFailureBase, isAcceptedPackagedRoleTerminalResult, isReceiptSettlementBindingClear, NAVIGATOR_INVOCATION_ENTRY, parseInvocationMarkerIdentity, } from "../navigator-invocation-identity.js";
33
32
  import { NO_RECEIPT_LIFECYCLE_ENTRY_TYPE, RECEIPT_DELIVERY_TURN_LIMIT, noReceiptLifecycleFacts, parseNoReceiptLifecycleFacts, } from "../receipt-delivery-policy.js";
34
33
  import { roleRunArtifactsDirectory } from "../role-run-placement.js";
@@ -1784,8 +1783,8 @@ async function publishAcceptedTerminalArtifacts(admitted, roleOutcome, coordinat
1784
1783
  ];
1785
1784
  }
1786
1785
  /** Publish one accepted seat's report/evidence face from the shared leaf table. */
1787
- export async function publishSeatAcceptedArtifacts(admitted, roleOutcome, coordinates, entries = [], options = {}) {
1788
- return publishDeclaredSeatArtifacts(admitted, roleOutcome, coordinates, entries, options);
1786
+ export async function publishSeatAcceptedArtifacts(admitted, roleOutcome, coordinates, entries = []) {
1787
+ return publishDeclaredSeatArtifacts(admitted, roleOutcome, coordinates, entries);
1789
1788
  }
1790
1789
  /**
1791
1790
  * Read session entries for lawful settlement. Missing path → undefined (absence).
@@ -1871,9 +1870,9 @@ async function settleSealedAcceptedOrToolResidual(admitted, authority, scope, ro
1871
1870
  /**
1872
1871
  * One settlement for every registered seat. The registry `settlement` leaf
1873
1872
  * picks sealed ledger, sealed-or-residual, or the accepted-tool scan.
1874
- * Seat evidence and the observed-method tail stay on the artifact face.
1873
+ * Seat evidence stays on the artifact face.
1875
1874
  */
1876
- async function settleSeat(admitted, authority, scope, options) {
1875
+ async function settleSeat(admitted, authority, scope) {
1877
1876
  const record = packagedRoleMetadata(admitted.role);
1878
1877
  if (record === undefined) {
1879
1878
  throw new Error(`no settlement for ${admitted.role}`);
@@ -1881,7 +1880,7 @@ async function settleSeat(admitted, authority, scope, options) {
1881
1880
  if (record.settlement === "accepted") {
1882
1881
  return trySettleAcceptedSeatTerminalResult(admitted, authority, scope);
1883
1882
  }
1884
- const publish = (roleOutcome, coordinates, entries) => publishDeclaredSeatArtifacts(admitted, roleOutcome, coordinates, entries, options);
1883
+ const publish = (roleOutcome, coordinates, entries) => publishDeclaredSeatArtifacts(admitted, roleOutcome, coordinates, entries);
1885
1884
  if (record.settlement === "residual") {
1886
1885
  return settleSealedAcceptedOrToolResidual(admitted, authority, scope, admitted.role, record.residualTool, record.residualScan, publish);
1887
1886
  }
@@ -1894,75 +1893,21 @@ async function settleSeat(admitted, authority, scope, options) {
1894
1893
  * Try to settle any registered seat. Undefined only for genuine absence.
1895
1894
  * Session malformation and publication exceptions keep their typed identity.
1896
1895
  */
1897
- export async function trySettleSeatTerminalResult(admitted, authority, options = {}, scope) {
1898
- return settleSeat(admitted, authority, scope, options);
1896
+ export async function trySettleSeatTerminalResult(admitted, authority, scope) {
1897
+ return settleSeat(admitted, authority, scope);
1899
1898
  }
1900
1899
  /**
1901
1900
  * Settle any registered seat. Throws when no lawful outcome is present.
1902
1901
  * Session-read and publication failures retain their typed identity.
1903
1902
  */
1904
- export async function settleSeatTerminalResult(admitted, authority, options = {}, scope) {
1905
- const settled = await settleSeat(admitted, authority, scope, options);
1903
+ export async function settleSeatTerminalResult(admitted, authority, scope) {
1904
+ const settled = await settleSeat(admitted, authority, scope);
1906
1905
  if (settled === undefined) {
1907
1906
  const label = admitted.role.charAt(0).toUpperCase() + admitted.role.slice(1);
1908
1907
  throw new Error(`${label} Role run completed without a lawful typed terminal result`);
1909
1908
  }
1910
1909
  return settled;
1911
1910
  }
1912
- function sessionMessageText(message) {
1913
- if (message === undefined)
1914
- return "";
1915
- if (typeof message.content === "string")
1916
- return message.content;
1917
- if (!Array.isArray(message.content))
1918
- return "";
1919
- const parts = [];
1920
- for (const part of message.content) {
1921
- if (typeof part === "object" &&
1922
- part !== null &&
1923
- !Array.isArray(part) &&
1924
- part.type === "text" &&
1925
- typeof part.text === "string") {
1926
- parts.push(part.text);
1927
- }
1928
- }
1929
- return parts.join("\n");
1930
- }
1931
- /**
1932
- * Locations a loaded packaged method may be observed at.
1933
- * The name is the loaded material; the configured path is the package copy.
1934
- */
1935
- export function observedMethodSkillOptions(packageRoot, material) {
1936
- return {
1937
- methodProvenance: material.provenance,
1938
- methodSkillPath: material.skillPath,
1939
- methodSkillConfiguredPath: resolvePackagedMethodSkillPath(packageRoot, material.name),
1940
- };
1941
- }
1942
- /**
1943
- * Observe packaged method Skill expansions from the session.
1944
- * The skill name is the caller's packaged method; home locations never count.
1945
- */
1946
- function extractObservedMethodInvocations(entries, options) {
1947
- const observed = [];
1948
- for (const entry of entries) {
1949
- if (entry?.type !== "message")
1950
- continue;
1951
- const message = entry.message;
1952
- if (message?.role !== "user")
1953
- continue;
1954
- const text = sessionMessageText(message);
1955
- if (text.length === 0)
1956
- continue;
1957
- const hit = observePackagedMethodSkillInvocation(text, {
1958
- name: options.name,
1959
- allowedLocations: options.allowedLocations,
1960
- });
1961
- if (hit !== undefined)
1962
- observed.push(hit);
1963
- }
1964
- return Object.freeze(observed);
1965
- }
1966
1911
  /**
1967
1912
  * #836: cost and the auditor's no-receipt facts ride beside the role's
1968
1913
  * testimony on the current attempt's candidate entry. Absence is omitted,
@@ -2027,30 +1972,7 @@ function doctorReportFacts(face, roleOutcome, entries) {
2027
1972
  ...(facts.auditNoReceipt === undefined ? {} : { auditNoReceipt: facts.auditNoReceipt }),
2028
1973
  };
2029
1974
  }
2030
- function observedMethodTail(face, entries, options) {
2031
- if (face.method === undefined)
2032
- return {};
2033
- if (face.method === "optional") {
2034
- return options.methodProvenance === undefined
2035
- ? {}
2036
- : { methodProvenance: options.methodProvenance };
2037
- }
2038
- if (options.methodProvenance === undefined
2039
- || options.methodSkillPath === undefined
2040
- || options.methodSkillConfiguredPath === undefined) {
2041
- throw new Error("observed method publication is missing packaged method coordinates");
2042
- }
2043
- const methodInvocations = extractObservedMethodInvocations(entries, {
2044
- name: options.methodProvenance.name,
2045
- allowedLocations: [options.methodSkillPath, options.methodSkillConfiguredPath],
2046
- });
2047
- return {
2048
- methodProvenance: options.methodProvenance,
2049
- methodInvocationObserved: methodInvocations.length > 0,
2050
- methodInvocations,
2051
- };
2052
- }
2053
- async function publishDeclaredSeatArtifacts(admitted, roleOutcome, coordinates, entries, options = {}) {
1975
+ async function publishDeclaredSeatArtifacts(admitted, roleOutcome, coordinates, entries) {
2054
1976
  const face = seatArtifactFace(admitted.role);
2055
1977
  const phase = face.reportPhase === true
2056
1978
  ? { phase: readAdmittedPath(admitted, "phase") }
@@ -2071,7 +1993,6 @@ async function publishDeclaredSeatArtifacts(admitted, roleOutcome, coordinates,
2071
1993
  sessionFile: coordinates.sessionFile,
2072
1994
  admittedRequestPath: admitted.admittedRequestPath,
2073
1995
  attachments: acceptedArtifactAttachmentRefs(admitted.attachments),
2074
- ...observedMethodTail(face, entries, options),
2075
1996
  },
2076
1997
  });
2077
1998
  }
@@ -2163,16 +2084,8 @@ export async function trySettleAcceptedSeatTerminalResult(admitted, authority, s
2163
2084
  return applySecretariatCountersignTerminal(admitted, authority, settled);
2164
2085
  }
2165
2086
  /** One settlement dispatch. The registry `settlement` leaf selects the path. */
2166
- export async function trySettlePublicSeat(admitted, authority, scope, material, packageRoot) {
2167
- const face = seatArtifactFace(admitted.role);
2168
- if (face.method === "observed" && material === undefined)
2169
- return undefined;
2170
- const options = face.method === "observed" && material !== undefined
2171
- ? observedMethodSkillOptions(packageRoot, material)
2172
- : face.method === "optional" && material !== undefined
2173
- ? { methodProvenance: material.provenance }
2174
- : {};
2175
- return settleSeat(admitted, authority, scope, options);
2087
+ export async function trySettlePublicSeat(admitted, authority, scope) {
2088
+ return settleSeat(admitted, authority, scope);
2176
2089
  }
2177
2090
  /**
2178
2091
  * #969 seat projection sole authority: 给事中 terminal (署|上呈) booked as a
@@ -1,6 +1,6 @@
1
1
  import { pickEngineAxis } from "../package-resources/engine-material.js";
2
- import { resolvePackagedMethodSkillPath, } from "../package-resources/method-skill.js";
3
2
  import { packagedRoleActivationFlags, packagedRoleMetadata, } from "../packaged-role-registry.js";
3
+ import { installedMethodSkillPath } from "./machine-method-skills.js";
4
4
  import { parentRunPathFromGatePointerInstruction } from "./run-lifecycle.js";
5
5
  export function projectRoleTurnRequest(admitted, roleDetails, options) {
6
6
  const cwd = admitted.projectRoot ?? admitted.repoRoot ?? admitted.cwd;
@@ -86,7 +86,7 @@ function activationForAdmitted(admitted) {
86
86
  return activation;
87
87
  }
88
88
  /** Skill bindings declared on the composition-root record for this admitted run. */
89
- function methodBindings(admitted, packageRoot) {
89
+ export function requiredMethodSkills(admitted) {
90
90
  const record = packagedRoleMetadata(admitted.role);
91
91
  const names = [];
92
92
  if (record !== undefined && "methodSkills" in record && record.methodSkills !== undefined) {
@@ -95,15 +95,23 @@ function methodBindings(admitted, packageRoot) {
95
95
  const apply = packagedSettleSkill(admitted);
96
96
  if (apply !== undefined && !names.includes(apply))
97
97
  names.push(apply);
98
- return names.map((name) => ({
99
- kind: "skill",
100
- path: resolvePackagedMethodSkillPath(packageRoot, name),
101
- }));
98
+ return names;
99
+ }
100
+ function methodBindings(admitted, home, host) {
101
+ if (host !== undefined && host !== "pi")
102
+ return [];
103
+ return requiredMethodSkills(admitted).flatMap((name) => {
104
+ const path = installedMethodSkillPath(home, name);
105
+ return path === undefined ? [] : [{
106
+ kind: "skill",
107
+ path,
108
+ }];
109
+ });
102
110
  }
103
111
  /** Registry activation and method bindings for one admitted public seat. */
104
- export function admittedSeatTurnDetails(admitted, packageRoot) {
112
+ export function admittedSeatTurnDetails(admitted, home, host) {
105
113
  return {
106
114
  activation: activationForAdmitted(admitted),
107
- methods: methodBindings(admitted, packageRoot),
115
+ methods: methodBindings(admitted, home, host),
108
116
  };
109
117
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akagilnc/pi-workflow-roles",
3
- "version": "0.1.5037",
3
+ "version": "0.1.5066",
4
4
  "description": "Soul-bound workflow roles for Pi",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -26,6 +26,8 @@
26
26
  },
27
27
  "files": [
28
28
  "dist",
29
+ "!dist/package-resources/method-skill.js",
30
+ "!dist/package-resources/method-skill-binding.js",
29
31
  "extensions",
30
32
  "scripts/generate-tool-execution-observation-schema.ts",
31
33
  "scripts/build-package.mjs",
@@ -9,7 +9,7 @@
9
9
  | `compliance-transport.ts` `AUDITOR_DOSSIER_PROMPT` | `本 run 卷宗已就绪。` | 改为台院同形路径指针。 |
10
10
  | `doctor-role.ts` case catalog | `provenance: "由留存 session 字节推导,封入受理回执。"` | 删。catalog 只留 cost 与证据指针。 |
11
11
  | `collector-role.ts` bounceInfrastructure | `请省略该字段后重新提交。` | 代码打回推翻自报已删。 |
12
- | `reviewer-role.ts` output description | `Standards/Spec 评审腿由 runtime 以取证子会话代跑…` | #836 改为「本席自调 code-review skill」。#917 后随包方法为 `ak-cross-m-review`;`resources/methods/code-review/` 已删,现役指针见 `resources/methods/ak-cross-m-review/SKILL.md`。 |
12
+ | `reviewer-role.ts` output description | `Standards/Spec 评审腿由 runtime 以取证子会话代跑…` | #836 改为「本席自调 code-review skill」。#917 后方法为 `ak-cross-m-review`;#1043 起不再随包,由 `ak-role setup` 从 Akagilnc/ak-cross-m-review 装入机器 `~/.agents/skills`。 |
13
13
  | `run-lifecycle.ts` A4.1 | `[ak-role:resume-continue]` | 生产码不再含此字面量。结算只跳过空轮与引擎指针续跑。 |
14
14
  | `run-lifecycle.ts` A4.2 | `重新读 <path>` | 前轮已删改写。 |
15
15
  | `submission-correctable-error.ts` A4.5 | `终局交卷并非本轮唯一工具调用。` | 删。Pi/ACP `deliverSubmissionRejection` 不再注入该句。 |
@@ -1,4 +1,4 @@
1
- import { chmod, copyFile, cp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
1
+ import { chmod, copyFile, mkdir, readFile, rm, writeFile } from "node:fs/promises";
2
2
  import { dirname, join, resolve } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { build } from "esbuild";
@@ -203,11 +203,6 @@ export async function buildPackageArtifacts() {
203
203
  await buildAcpProductionHost();
204
204
  await buildHeadlessProductionHost();
205
205
  await buildMigrateBookTopology();
206
- const pluginDir = join("dist", "method-host-plugin");
207
- await rm(pluginDir, { recursive: true, force: true });
208
- await mkdir(pluginDir, { recursive: true });
209
- await cp("resources/method-host-plugin/.claude-plugin", join(pluginDir, ".claude-plugin"), { recursive: true });
210
- await cp("resources/methods", join(pluginDir, "skills"), { recursive: true });
211
206
  // Packaged handbook/playbook paths resolve via injected packageRoot (#962) —
212
207
  // do not mirror resources/ into dist/resources (one authority, no parallel copy).
213
208
  }
@@ -94,8 +94,6 @@ export function headlessTurnArgs(options: {
94
94
  readonly effort?: string;
95
95
  /** Fresh session: pass as session id. Resume: pass as resume id. */
96
96
  readonly session: { readonly kind: "new"; readonly id: string } | { readonly kind: "resume"; readonly id: string };
97
- /** Packaged method plugin dir (`--plugin-dir`). */
98
- readonly pluginDir?: string;
99
97
  }): string[] {
100
98
  const { description } = options;
101
99
  const args: string[] = [
@@ -107,7 +105,6 @@ export function headlessTurnArgs(options: {
107
105
  if (options.jsonSchema !== undefined) {
108
106
  args.push(description.jsonSchemaFlag, JSON.stringify(options.jsonSchema));
109
107
  }
110
- if (options.pluginDir) args.push("--plugin-dir", options.pluginDir);
111
108
  if (options.mcpConfigPath !== undefined && options.mcpConfigPath !== "") {
112
109
  args.push(description.mcpConfigFlag, options.mcpConfigPath);
113
110
  }
@@ -23,12 +23,6 @@ import {
23
23
  } from "../prepared-role-turn.ts";
24
24
 
25
25
  import { reportHostSessionEvent } from "../host-session-record.ts";
26
- import {
27
- applyClaudeSkillInvocation,
28
- applyCodexSkillInvocation,
29
- hostMethodSkills,
30
- packagedMethodPluginDir,
31
- } from "../host-native-method.ts";
32
26
  import {
33
27
  closeJsonSchemaForCodex,
34
28
  codexTurnArgs,
@@ -418,7 +412,6 @@ function buildTurnArgs(options: {
418
412
  readonly sessionKind: "new" | "resume";
419
413
  readonly cwd: string;
420
414
  readonly writableRoots?: readonly string[];
421
- readonly pluginDir?: string;
422
415
  }): readonly string[] {
423
416
  if (isCodexExecDescription(options.description)) {
424
417
  if (options.sessionKind === "resume" && !options.sessionId) {
@@ -451,7 +444,6 @@ function buildTurnArgs(options: {
451
444
  ...(options.model === undefined ? {} : { model: options.model }),
452
445
  ...(options.effort === undefined ? {} : { effort: options.effort }),
453
446
  session: { kind: options.sessionKind, id: options.sessionId },
454
- ...(options.pluginDir === undefined ? {} : { pluginDir: options.pluginDir }),
455
447
  });
456
448
  }
457
449
 
@@ -460,7 +452,7 @@ export function createHeadlessRoleTurnHost(config: HeadlessRoleTurnHostConfig):
460
452
  return createSerializedRoleTurnHost(async (request): Promise<RoleTurnResult> => {
461
453
  const prepared = await config.prepare(request);
462
454
  const systemPrompt = renderSystemPromptOverride(prepared.systemPrompt);
463
- const codex = isCodexExecDescription(config.description);
455
+ const codex = isCodexExecDescription(config.description);
464
456
  let outcome: RoleTurnResult = failure("session", "HeadlessNoOutcome", "no-outcome");
465
457
  try {
466
458
  // Claude mints a package UUID for --session-id; codex waits for thread.started.
@@ -486,10 +478,6 @@ export function createHeadlessRoleTurnHost(config: HeadlessRoleTurnHostConfig):
486
478
  await writeFile(systemPromptPath, systemPrompt, "utf8");
487
479
  let mcpConfigPath: string | undefined;
488
480
  let outputSchemaPath: string | undefined;
489
- let pluginDir: string | undefined;
490
- let applyMethodPrompt: (prompt: string) => string = codex
491
- ? (prompt) => applyCodexSkillInvocation(request.methods, prompt)
492
- : (prompt) => prompt;
493
481
  if (codex) {
494
482
  // #959: navigator is a prose-exit seat — no closed output-schema.
495
483
  if (prepared.terminatingToolName !== NAVIGATOR_OUTPUT_TOOL_NAME) {
@@ -507,14 +495,6 @@ export function createHeadlessRoleTurnHost(config: HeadlessRoleTurnHostConfig):
507
495
  `${JSON.stringify(headlessMcpConfigDocument(prepared.mcpServers), null, 2)}\n`,
508
496
  "utf8",
509
497
  );
510
- if (hostMethodSkills(request.methods).length > 0) {
511
- const packageRoot = env.AK_PACKAGE_ROOT ?? process.env.AK_PACKAGE_ROOT;
512
- if (typeof packageRoot !== "string" || packageRoot === "") {
513
- throw new Error("claude method plugin-dir requires AK_PACKAGE_ROOT");
514
- }
515
- pluginDir = packagedMethodPluginDir(packageRoot);
516
- applyMethodPrompt = (prompt) => applyClaudeSkillInvocation(request.methods, prompt);
517
- }
518
498
  }
519
499
 
520
500
  const sessionParent = config.sessionIdentity.resolveSessionFile(request.principal);
@@ -542,7 +522,6 @@ export function createHeadlessRoleTurnHost(config: HeadlessRoleTurnHostConfig):
542
522
  sessionKind,
543
523
  cwd: request.cwd,
544
524
  ...(gitCommonDir === undefined ? {} : { writableRoots: [gitCommonDir] }),
545
- ...(pluginDir === undefined ? {} : { pluginDir }),
546
525
  });
547
526
  } catch (error) {
548
527
  const message = error instanceof Error ? error.message : String(error);
@@ -560,7 +539,7 @@ export function createHeadlessRoleTurnHost(config: HeadlessRoleTurnHostConfig):
560
539
  args,
561
540
  cwd: request.cwd,
562
541
  env,
563
- stdin: request.continuation.kind === "resume" ? prompt : applyMethodPrompt(prompt),
542
+ stdin: prompt,
564
543
  ...(abortSignal === undefined ? {} : { signal: abortSignal }),
565
544
  ...(request.timeoutMs === undefined ? {} : { timeoutMs: request.timeoutMs }),
566
545
  onStdoutLine(line) {
@@ -74,7 +74,7 @@ export class ExplicitInternalActivationError extends Error {
74
74
  }
75
75
  }
76
76
 
77
- /** Packaged method skill binding (zero/one/many). */
77
+ /** Required machine-installed method Skill (zero/one/many). */
78
78
  export type MethodBinding = {
79
79
  readonly kind: "skill";
80
80
  readonly path: string;
@@ -350,33 +350,13 @@ type HostGatekeeperSubject = {
350
350
  };
351
351
  /** Gatekeeper non-pass faces returned to parent (#836 includes transport_failure; never kill leg). */
352
352
  type HostGatekeeperNonPass = { readonly status: "continue" | "escalate" | "no_receipt" | "transport_failure" } & Record<string, unknown>;
353
- export type HostSubmissionNonPass =
354
- | HostGatekeeperNonPass
355
- | { readonly code: "coder_skill_expansion_evidence_missing" };
353
+ export type HostSubmissionNonPass = HostGatekeeperNonPass;
356
354
  export type HostGatekeeperActions = {
357
355
  failInfrastructure(error: unknown, context: HostContext, toolCallId?: string): never;
358
356
  /** Envelope-owned execute→tool_result bridge for any structured submission non-pass. */
359
357
  bindSubmissionNonPass(toolCallId: string, result: HostSubmissionNonPass): void;
360
358
  };
361
359
 
362
- export type HostSkillExpansionEvidence = Readonly<{
363
- name: string;
364
- location: string;
365
- content: string;
366
- userMessage: string;
367
- }>;
368
-
369
- /** Host capability declaration (contract verb ④). */
370
- export type HostCapabilityDeclaration = Readonly<{
371
- skillExpansion(prompt: string): HostSkillExpansionEvidence | undefined;
372
- /**
373
- * Pi-only: recover the plain original request from a native skill turn text
374
- * (argv may already carry `/skill:<name>` from the Pi adapter). Absent on
375
- * non-pi hosts so role body never parses Pi slash syntax (ADR 0082).
376
- */
377
- skillOriginalRequest?(name: string, text: string): string;
378
- }>;
379
-
380
360
  /** Host-owned effects used by the shared activation envelope. */
381
361
  export interface RoleEnvelopeHost {
382
362
  readonly host: RoleHost;
@@ -388,7 +368,6 @@ export interface RoleEnvelopeHost {
388
368
 
389
369
  /** The activation surface consumed by package role factories. */
390
370
  export interface RoleHost {
391
- readonly capabilities?: HostCapabilityDeclaration;
392
371
  /** Deliver a typed correctable rejection into the current durable session's model context. */
393
372
  deliverSubmissionRejection?(rejection: { readonly kind: "correctable-rejection"; readonly code: string; readonly toolCallIds: readonly string[] }): void | Promise<void>;
394
373
  registerFlag(name: string, definition:
@@ -56,9 +56,8 @@ export const HOST_DESCRIPTIONS: Readonly<Record<string, AcpHostDescription>> = O
56
56
  * Headless CLI family (#645 / #646). Claude print-mode is the first row;
57
57
  * codex exec (#646) adds another. Protocol-specific argv/parse live in
58
58
  * headless-host helpers (#752 per-host impl).
59
- * Claude fixedArgs: print mode, full permissions. stream-json + verbose: live
60
- * host events for sitian records (#811); result is last line. Forced methods
61
- * ride `--plugin-dir` (#922); operator skill/setting surfaces stay open.
59
+ * Claude fixedArgs: print mode. stream-json + verbose: live
60
+ * host events for sitian records (#811); result is last line.
62
61
  */
63
62
  export const HEADLESS_HOST_DESCRIPTIONS: Readonly<Record<string, HeadlessHostDescription>> = Object.freeze({
64
63
  "claude": Object.freeze({
@@ -42,7 +42,6 @@ export type PackagedArtifactFace = {
42
42
  readonly reportPhase?: true;
43
43
  readonly evidenceRole?: true;
44
44
  readonly leaves: readonly PackagedArtifactLeaf[];
45
- readonly method?: "optional" | "observed";
46
45
  readonly doctorReportFacts?: true;
47
46
  };
48
47
 
@@ -132,7 +131,6 @@ export const PUBLIC_ROLE_RECORDS = [
132
131
  { key: "prerequisitesPath", omitUndefined: true },
133
132
  { key: "prerequisites" },
134
133
  ],
135
- method: "observed",
136
134
  },
137
135
  boardPlacement: "marshal",
138
136
  activationFlags: [
@@ -158,7 +156,6 @@ export const PUBLIC_ROLE_RECORDS = [
158
156
  worker: true,
159
157
  applyMethod: "tdd",
160
158
  /** Method-material load failure keeps the activation cause (not reviewer/fixer). */
161
- methodLoadFailureCause: "activation",
162
159
  boardPlacement: "coder",
163
160
  phases: ["plan", "apply"],
164
161
  outputTool: CODER_OUTPUT_TOOL_NAME,
@@ -170,7 +167,6 @@ export const PUBLIC_ROLE_RECORDS = [
170
167
  { key: "phase" },
171
168
  { key: "taskPath" },
172
169
  ],
173
- method: "optional",
174
170
  },
175
171
  activationFlags: [
176
172
  { field: "taskPath", flag: "ak-coder-task", binds: "input" },
@@ -212,7 +208,6 @@ export const PUBLIC_ROLE_RECORDS = [
212
208
  { key: "authorityRefs", copyArray: true },
213
209
  { key: "callerProvenance", callerProvenance: true },
214
210
  ],
215
- method: "observed",
216
211
  },
217
212
  /** Frozen base/lens/authority become the initial prompt; instruction follows. */
218
213
  transportPrompt: "skill-args",
@@ -311,7 +306,6 @@ export const PUBLIC_ROLE_RECORDS = [
311
306
  methodSkills: ["resolving-merge-conflicts"],
312
307
  settleMethod: "resolving-merge-conflicts",
313
308
  /** Method-material load failure keeps the activation cause (not reviewer/fixer). */
314
- methodLoadFailureCause: "activation",
315
309
  phases: [null],
316
310
  outputTool: MERGER_OUTPUT_TOOL_NAME,
317
311
  settlement: "residual",
@@ -324,7 +318,6 @@ export const PUBLIC_ROLE_RECORDS = [
324
318
  { key: "mergerInputPath" },
325
319
  { key: "derived" },
326
320
  ],
327
- method: "observed",
328
321
  },
329
322
  activationFlags: [
330
323
  { field: "inputPath", from: "mergerInputPath", flag: "ak-merger-input", binds: "input" },
@@ -582,6 +575,20 @@ export function packagedRoleMetadata(role: string): PackagedRoleMetadata | undef
582
575
  return PACKAGED_ROLE_REGISTRY.find((entry) => entry.role === role);
583
576
  }
584
577
 
578
+ /** Names any public seat may require. Setup and missing-Skill checks both read this. */
579
+ export function packagedMethodSkillNames(): readonly string[] {
580
+ const names: string[] = [];
581
+ for (const record of PACKAGED_ROLE_REGISTRY) {
582
+ if ("methodSkills" in record && record.methodSkills !== undefined) {
583
+ for (const name of record.methodSkills) if (!names.includes(name)) names.push(name);
584
+ }
585
+ if ("applyMethod" in record && record.applyMethod !== undefined && !names.includes(record.applyMethod)) {
586
+ names.push(record.applyMethod);
587
+ }
588
+ }
589
+ return names;
590
+ }
591
+
585
592
  /** Review officers (台院 / 符宝郎 / 审刑院). Absent on every other seat. */
586
593
  export function isOfficerReviewSeat(role: string): boolean {
587
594
  const record = packagedRoleMetadata(role);
@@ -652,13 +659,6 @@ export function packagedRoleOutputTool(role: string): string | undefined {
652
659
  return packagedRoleMetadata(role)?.outputTool;
653
660
  }
654
661
 
655
- /** Method-material load failure cause declared on the seat. Absent means no typed cause. */
656
- export function packagedMethodLoadFailureCause(role: string): "activation" | undefined {
657
- const record = packagedRoleMetadata(role);
658
- if (record === undefined || !("methodLoadFailureCause" in record)) return undefined;
659
- return record.methodLoadFailureCause;
660
- }
661
-
662
662
  /** Diarist binds a board ticket onto its own run. Other seats do not. */
663
663
  export function packagedBindsBoardTicket(role: string): boolean {
664
664
  const record = packagedRoleMetadata(role);
package/src/pi/adapter.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import {
2
- parseSkillBlock,
3
2
  type BeforeAgentStartEventResult,
4
3
  type ExtensionAPI,
5
4
  type ExtensionContext,
@@ -166,32 +165,6 @@ export function createPiRoleHostAdapter(
166
165
  deliverSubmissionRejection(_rejection) {
167
166
  // #836 删 1/A4.5: no package-authored non-sole resume sentence.
168
167
  },
169
- capabilities: {
170
- skillExpansion(prompt) {
171
- const parsed = parseSkillBlock(prompt);
172
- if (parsed == null) return undefined;
173
- const userMessage = parsed.userMessage ?? "";
174
- return Object.freeze({
175
- name: parsed.name,
176
- location: parsed.location,
177
- content: parsed.content,
178
- userMessage,
179
- });
180
- },
181
- /** Recover plain original request from Pi-native `/skill:` turn text (ADR 0082). */
182
- skillOriginalRequest(name, text) {
183
- const token = `/skill:${name}`;
184
- const trimmed = text.trimStart();
185
- if (
186
- trimmed === token
187
- || trimmed.startsWith(`${token} `)
188
- || trimmed.startsWith(`${token}\n`)
189
- ) {
190
- return text.slice(text.indexOf(token) + token.length).trim();
191
- }
192
- return text.trim();
193
- },
194
- },
195
168
  registerFlag: (name, definition) => pi.registerFlag(name, definition),
196
169
  getFlag: (name) => pi.getFlag(name),
197
170
  registerTool: (tool) => pi.registerTool(toPiToolDefinition(
@@ -6,7 +6,7 @@
6
6
  import { execFile, spawn } from "node:child_process";
7
7
  import { constants } from "node:fs";
8
8
  import { access, appendFile, readFile, realpath } from "node:fs/promises";
9
- import { basename, delimiter, dirname, isAbsolute, join, resolve } from "node:path";
9
+ import { delimiter, dirname, isAbsolute, join, resolve } from "node:path";
10
10
  import { platform } from "node:process";
11
11
  import { promisify } from "node:util";
12
12
  import { randomUUID } from "node:crypto";
@@ -86,38 +86,12 @@ function buildMethodArgs(methods: readonly MethodBinding[]): string[] {
86
86
  const skillArgs: string[] = [];
87
87
  for (const method of methods) {
88
88
  if (method.kind === "skill") {
89
- skillArgs.push("--skill", method.path);
89
+ skillArgs.push("--skill", dirname(method.path));
90
90
  }
91
91
  }
92
92
  return skillArgs;
93
93
  }
94
94
 
95
- /**
96
- * Pi-native `/skill:<name>` for a single forced method (ADR 0082: pi is one adapter
97
- * with no privilege; Pi-only seams stay inside the pi adapter).
98
- * Driven by typed RoleTurnRequest.methods — middle-layer decision, Pi-only syntax.
99
- * Zero/many methods leave the prompt alone (Fixer optional pair stays `--skill` only).
100
- */
101
- export function applyPiNativeSkillInvocation(
102
- methods: readonly MethodBinding[],
103
- prompt: string,
104
- ): string {
105
- const skills = methods.filter((method) => method.kind === "skill");
106
- if (skills.length !== 1) return prompt;
107
- const name = basename(dirname(skills[0]!.path));
108
- if (name.length === 0) return prompt;
109
- const token = `/skill:${name}`;
110
- const trimmed = prompt.trimStart();
111
- if (
112
- trimmed === token
113
- || trimmed.startsWith(`${token} `)
114
- || trimmed.startsWith(`${token}\n`)
115
- ) {
116
- return prompt;
117
- }
118
- return prompt.length === 0 ? token : `${token} ${prompt}`;
119
- }
120
-
121
95
  /**
122
96
  * Pi last-hop argv after `--no-extensions -e entry` (#819).
123
97
  * Activation flag membership comes from middle-layer projectActivationFlags;
@@ -165,9 +139,7 @@ function piUserDialogueBody(request: RoleTurnRequest): string {
165
139
  const _exhaustive: never = request.continuation;
166
140
  return _exhaustive;
167
141
  })();
168
- return request.continuation.kind === "resume"
169
- ? rawPrompt
170
- : applyPiNativeSkillInvocation(request.methods, rawPrompt);
142
+ return rawPrompt;
171
143
  }
172
144
 
173
145
  export type PiSpawnRunner = (