@akagilnc/pi-workflow-roles 0.1.5015 → 0.1.5063
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.
- package/README.md +2 -2
- package/README.zh-CN.md +2 -2
- package/THIRD_PARTY_NOTICES.md +8 -8
- package/dist/acp-host/production-host.js +525 -978
- package/dist/headless-host/description.js +0 -2
- package/dist/headless-host/production-host.js +528 -1014
- package/dist/host-descriptions.js +2 -3
- package/dist/migrate-book-topology.js +7 -12
- package/dist/packaged-role-registry.js +20 -18
- package/dist/pi/role-turn-host.js +3 -27
- package/dist/public-cli/cli.js +23 -2
- package/dist/public-cli/countersign-run.js +13 -8
- package/dist/public-cli/instruction-seat-run.js +75 -107
- package/dist/public-cli/invocation.js +13 -32
- package/dist/public-cli/machine-method-skills.js +150 -0
- package/dist/public-cli/main.js +549 -679
- package/dist/public-cli/post-admission.js +10 -5
- package/dist/public-cli/registry.js +2 -1
- package/dist/public-cli/run-lifecycle.js +12 -15
- package/dist/public-cli/seat-ticket-binding.js +5 -8
- package/dist/public-cli/settlement.js +12 -99
- package/dist/public-cli/turn-request.js +16 -8
- package/dist/public-role-summons.js +8 -3
- package/package.json +5 -1
- package/resources/countersign-ticket-issue.md +5 -0
- package/resources/diarist-collect.md +1 -0
- package/resources/secretariat-ticket-identity.md +15 -0
- package/scripts/build-package.mjs +1 -6
- package/src/headless-host/description.ts +0 -3
- package/src/headless-host/role-turn-host.ts +2 -23
- package/src/host-contracts.ts +2 -23
- package/src/host-descriptions.ts +2 -3
- package/src/packaged-role-registry.ts +17 -16
- package/src/pi/adapter.ts +0 -27
- package/src/pi/role-turn-host.ts +3 -31
- package/src/public-cli/cli.ts +24 -2
- package/src/public-cli/countersign-run.ts +17 -10
- package/src/public-cli/instruction-seat-run.ts +75 -105
- package/src/public-cli/invocation.ts +10 -38
- package/src/public-cli/machine-method-skills.ts +153 -0
- package/src/public-cli/post-admission.ts +12 -6
- package/src/public-cli/registry.ts +1 -0
- package/src/public-cli/run-lifecycle.ts +12 -13
- package/src/public-cli/seat-ticket-binding.ts +5 -8
- package/src/public-cli/settlement.ts +6 -138
- package/src/public-cli/turn-request.ts +24 -16
- package/src/public-role-summons.ts +16 -3
- package/src/reviewer-role.ts +1 -12
- package/src/role-envelope.ts +0 -13
- package/src/role-runtime-dependencies.ts +0 -13
- package/src/role-runtime.ts +4 -56
- package/src/worker-role.ts +1 -81
- package/dist/method-host-plugin/.claude-plugin/plugin.json +0 -5
- package/dist/method-host-plugin/skills/ak-cross-m-review/CONTEXT.md +0 -48
- package/dist/method-host-plugin/skills/ak-cross-m-review/LICENSE +0 -21
- package/dist/method-host-plugin/skills/ak-cross-m-review/SKILL.md +0 -170
- package/dist/method-host-plugin/skills/ak-cross-m-review/prompts/cmr-completeness.md +0 -118
- package/dist/method-host-plugin/skills/ak-cross-m-review/prompts/cmr-reviewer.md +0 -128
- package/dist/method-host-plugin/skills/ak-cross-m-review/provenance.json +0 -41
- package/dist/method-host-plugin/skills/diagnosing-bugs/SKILL.md +0 -134
- package/dist/method-host-plugin/skills/diagnosing-bugs/agents/openai.yaml +0 -3
- package/dist/method-host-plugin/skills/diagnosing-bugs/provenance.json +0 -31
- package/dist/method-host-plugin/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +0 -41
- package/dist/method-host-plugin/skills/resolving-merge-conflicts/SKILL.md +0 -14
- package/dist/method-host-plugin/skills/resolving-merge-conflicts/agents/openai.yaml +0 -3
- package/dist/method-host-plugin/skills/resolving-merge-conflicts/provenance.json +0 -26
- package/dist/method-host-plugin/skills/tdd/SKILL.md +0 -38
- package/dist/method-host-plugin/skills/tdd/agents/openai.yaml +0 -3
- package/dist/method-host-plugin/skills/tdd/mocking.md +0 -59
- package/dist/method-host-plugin/skills/tdd/provenance.json +0 -36
- package/dist/method-host-plugin/skills/tdd/tests.md +0 -77
- package/dist/package-resources/method-skill.js +0 -259
- package/resources/method-host-plugin/.claude-plugin/plugin.json +0 -5
- package/resources/methods/ak-cross-m-review/CONTEXT.md +0 -48
- package/resources/methods/ak-cross-m-review/LICENSE +0 -21
- package/resources/methods/ak-cross-m-review/SKILL.md +0 -170
- package/resources/methods/ak-cross-m-review/prompts/cmr-completeness.md +0 -118
- package/resources/methods/ak-cross-m-review/prompts/cmr-reviewer.md +0 -128
- package/resources/methods/ak-cross-m-review/provenance.json +0 -41
- package/resources/methods/diagnosing-bugs/SKILL.md +0 -134
- package/resources/methods/diagnosing-bugs/agents/openai.yaml +0 -3
- package/resources/methods/diagnosing-bugs/provenance.json +0 -31
- package/resources/methods/diagnosing-bugs/scripts/hitl-loop.template.sh +0 -41
- package/resources/methods/resolving-merge-conflicts/SKILL.md +0 -14
- package/resources/methods/resolving-merge-conflicts/agents/openai.yaml +0 -3
- package/resources/methods/resolving-merge-conflicts/provenance.json +0 -26
- package/resources/methods/tdd/SKILL.md +0 -38
- package/resources/methods/tdd/agents/openai.yaml +0 -3
- package/resources/methods/tdd/mocking.md +0 -59
- package/resources/methods/tdd/provenance.json +0 -36
- package/resources/methods/tdd/tests.md +0 -77
- package/src/canonical-skill-binding.ts +0 -118
- package/src/host-native-method.ts +0 -185
- package/src/package-resources/method-skill-binding.ts +0 -60
- package/src/package-resources/method-skill.ts +0 -363
|
@@ -104,8 +104,9 @@ function withOnceSuccessfulBeforeDispatch(adapters) {
|
|
|
104
104
|
beforeDispatch: async (admitted, lease) => {
|
|
105
105
|
if (succeeded)
|
|
106
106
|
return;
|
|
107
|
-
await hook(admitted, lease);
|
|
107
|
+
const result = await hook(admitted, lease);
|
|
108
108
|
succeeded = true;
|
|
109
|
+
return result;
|
|
109
110
|
},
|
|
110
111
|
};
|
|
111
112
|
}
|
|
@@ -333,9 +334,8 @@ export async function dispatchPostAdmissionTurn(input) {
|
|
|
333
334
|
};
|
|
334
335
|
}
|
|
335
336
|
try {
|
|
336
|
-
// #858:
|
|
337
|
-
//
|
|
338
|
-
// or reject missing/malformed declarations. An existing binding wins.
|
|
337
|
+
// #858: the first typed assertion files an unbound run. Later receipts
|
|
338
|
+
// remain untouched; this seam does not adjudicate a ticket change.
|
|
339
339
|
if (admitted.ticketNumber === undefined) {
|
|
340
340
|
const rows = await readRecordedSubmissionRows(admitted.projectRoot, admitted.runId, { home: homeFromRunDirectory(admitted.runDirectory), sessionParent: join(admitted.runDirectory, "session", "session.jsonl") });
|
|
341
341
|
const asserted = rows
|
|
@@ -429,7 +429,10 @@ export async function dispatchPostAdmissionTurn(input) {
|
|
|
429
429
|
// (#840 父子不层叠).
|
|
430
430
|
if (adapters.beforeDispatch !== undefined) {
|
|
431
431
|
try {
|
|
432
|
-
await adapters.beforeDispatch(admitted, lease);
|
|
432
|
+
const paused = await adapters.beforeDispatch(admitted, lease);
|
|
433
|
+
if (paused !== undefined) {
|
|
434
|
+
return { exitCode: 0, admitted, terminal: paused, skipAutoResume: true };
|
|
435
|
+
}
|
|
433
436
|
}
|
|
434
437
|
catch (error) {
|
|
435
438
|
const settled = (await presentControlledFailure(admitted, withEngineDetourInvocationScope({
|
|
@@ -860,6 +863,7 @@ export function resumeTurnRequestProjectionOptions(admitted, request, env, summo
|
|
|
860
863
|
return {
|
|
861
864
|
packageRoot: env.packageRoot,
|
|
862
865
|
home: env.home,
|
|
866
|
+
...(env.host === undefined ? {} : { host: env.host }),
|
|
863
867
|
agentDir: env.agentDir,
|
|
864
868
|
...(env.model === undefined ? {} : { model: env.model }),
|
|
865
869
|
...pickEngineAxis(env),
|
|
@@ -881,6 +885,7 @@ export function roleTurnOptions(env, admitted, continuation) {
|
|
|
881
885
|
return {
|
|
882
886
|
packageRoot: env.packageRoot,
|
|
883
887
|
home: env.home,
|
|
888
|
+
...(env.host === undefined ? {} : { host: env.host }),
|
|
884
889
|
agentDir: env.agentDir,
|
|
885
890
|
...(env.model === undefined ? {} : { model: env.model }),
|
|
886
891
|
...pickEngineAxis(env),
|
|
@@ -816,11 +816,10 @@ async function runHasFormedSessionPrincipal(runDirectory) {
|
|
|
816
816
|
/**
|
|
817
817
|
* Locate the latest retained run for one seat under a book (#637 / #747).
|
|
818
818
|
* Same walk surface as findRunDirectoryById (listBookRunDirectories). Match by
|
|
819
|
-
* parent run path (officer / gate seats, #747 / #987)
|
|
820
|
-
*
|
|
821
|
-
* runs that formed a session principal. No parallel index
|
|
822
|
-
*
|
|
823
|
-
* `ak-role resume <runId>`.
|
|
819
|
+
* parent run path (officer / gate seats, #747 / #987), narrowed to a supplied
|
|
820
|
+
* typed ticket for same-ticket gate re-summons. runId is UUIDv7 — lexicographic
|
|
821
|
+
* max is latest among runs that formed a session principal. No parallel index;
|
|
822
|
+
* callers can use explicit `ak-role resume <runId>`.
|
|
824
823
|
* Only a truly missing book directory means no history; damage/permission errors propagate.
|
|
825
824
|
*/
|
|
826
825
|
export async function findLatestRunIdForSeatTicket(input) {
|
|
@@ -831,11 +830,7 @@ export async function findLatestRunIdForSeatTicket(input) {
|
|
|
831
830
|
const bookDir = activationBookDirectory(ledgerHome, input.bookKey);
|
|
832
831
|
let runDirectories;
|
|
833
832
|
try {
|
|
834
|
-
|
|
835
|
-
// same-parent matching below still selects the actual prior leg.
|
|
836
|
-
runDirectories = await listBookRunDirectories(input.ticketNumber === undefined
|
|
837
|
-
? bookDir
|
|
838
|
-
: join(bookDir, String(input.ticketNumber)));
|
|
833
|
+
runDirectories = await listBookRunDirectories(input.ticketNumber === undefined ? bookDir : join(bookDir, String(input.ticketNumber)));
|
|
839
834
|
}
|
|
840
835
|
catch (error) {
|
|
841
836
|
if (errorCodeOf(error) === "ENOENT")
|
|
@@ -852,7 +847,9 @@ export async function findLatestRunIdForSeatTicket(input) {
|
|
|
852
847
|
if (runId.length === 0)
|
|
853
848
|
continue;
|
|
854
849
|
const parentPath = await readRunParentPath(runDirectory);
|
|
855
|
-
|
|
850
|
+
// The parent's ticket can change after this child was admitted. Within one
|
|
851
|
+
// book the run leaf is its stable identity; directory placement is not.
|
|
852
|
+
if (parentPath !== input.parentRunPath && basename(parentPath ?? "") !== basename(input.parentRunPath))
|
|
856
853
|
continue;
|
|
857
854
|
// Durable fact: never resume-select a provisional that never formed principal.
|
|
858
855
|
if (!(await runHasFormedSessionPrincipal(runDirectory)))
|
|
@@ -935,7 +932,7 @@ function restoredTicketFields(fields) {
|
|
|
935
932
|
: { courtTicketNumbers: fields.courtTicketNumbers }),
|
|
936
933
|
};
|
|
937
934
|
}
|
|
938
|
-
async function loadResumableRunRecord(home, runId, authority) {
|
|
935
|
+
async function loadResumableRunRecord(home, runId, authority, allowUnformedAdmitted = false) {
|
|
939
936
|
const runDirectory = await findRunDirectoryById(home, runId);
|
|
940
937
|
if (runDirectory === undefined) {
|
|
941
938
|
throw new CliUsageError(`unknown role run id: ${runId}`);
|
|
@@ -952,7 +949,7 @@ async function loadResumableRunRecord(home, runId, authority) {
|
|
|
952
949
|
throw new CliUsageError(`unknown role run id: ${runId}`);
|
|
953
950
|
}
|
|
954
951
|
const { run, principal } = materialized;
|
|
955
|
-
if (!(await isDurablePrincipalAvailable(principal, authority))) {
|
|
952
|
+
if (!(allowUnformedAdmitted && run.state === "admitted") && !(await isDurablePrincipalAvailable(principal, authority))) {
|
|
956
953
|
throw new CliUsageError(`role run Pi session principal is unavailable: ${runId}`);
|
|
957
954
|
}
|
|
958
955
|
// Reconstruct admitted identity from durable run record + admitted-request.json.
|
|
@@ -1271,8 +1268,8 @@ export async function peekRoleRunRole(home, runId) {
|
|
|
1271
1268
|
* selects the existing restore checks. The stored native host session id is
|
|
1272
1269
|
* read on the public explicit resume seam, not from this load.
|
|
1273
1270
|
*/
|
|
1274
|
-
export async function loadResumablePublicRole(home, runId, authority) {
|
|
1275
|
-
const loaded = await loadResumableRunRecord(home, runId, authority);
|
|
1271
|
+
export async function loadResumablePublicRole(home, runId, authority, allowUnformedAdmitted = false) {
|
|
1272
|
+
const loaded = await loadResumableRunRecord(home, runId, authority, allowUnformedAdmitted);
|
|
1276
1273
|
return seatLoadedResult(loaded, admitResumedRole(loaded));
|
|
1277
1274
|
}
|
|
1278
1275
|
/**
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared same-parent resume seam for gate / officer seats (#635 / #637 / #747 / #987).
|
|
3
3
|
*
|
|
4
|
-
* Lookup
|
|
5
|
-
*
|
|
6
|
-
* `ak-role resume <runId>`.
|
|
7
|
-
* keep this seam. Lookup/resume failures propagate (失败诚实) — never wash into
|
|
4
|
+
* Lookup uses the parent run path; a typed ticket narrows same-ticket gate
|
|
5
|
+
* re-summons, never creates an issue identity. Callers can also use explicit
|
|
6
|
+
* `ak-role resume <runId>`. Lookup/resume failures propagate (失败诚实) — never wash into
|
|
8
7
|
* a fresh mint. Returns undefined when the caller declared an explicit fresh
|
|
9
8
|
* summons (`ak-role new`) or when no prior run exists; both mint new.
|
|
10
9
|
* freshSummons is required so no seat can drift back into its own skip branch.
|
|
@@ -13,7 +12,7 @@ import { resolveBookKeyFromGit } from "../activation-ledger-git.js";
|
|
|
13
12
|
import { findLatestRunIdForSeatTicket, } from "./run-lifecycle.js";
|
|
14
13
|
/**
|
|
15
14
|
* Sole same-seat → resume decision by parent run path (#637 / #724 / #747 / #987).
|
|
16
|
-
* A typed ticket
|
|
15
|
+
* A supplied typed ticket only narrows the prior-run search. When a prior run is
|
|
17
16
|
* found, resume carries this summons' materials. Lookup/resume failures
|
|
18
17
|
* propagate (失败诚实) — never wash into a fresh mint. Returns undefined when
|
|
19
18
|
* the caller declared an explicit fresh summons (`ak-role new`), the parent
|
|
@@ -30,9 +29,7 @@ export async function tryResumeSameTicketSeatRun(input) {
|
|
|
30
29
|
bookKey: resolveBookKeyFromGit(input.projectRoot),
|
|
31
30
|
role: input.role,
|
|
32
31
|
parentRunPath: input.parentRunPath,
|
|
33
|
-
...(input.ticketNumber === undefined
|
|
34
|
-
? {}
|
|
35
|
-
: { ticketNumber: input.ticketNumber }),
|
|
32
|
+
...(input.ticketNumber === undefined ? {} : { ticketNumber: input.ticketNumber }),
|
|
36
33
|
});
|
|
37
34
|
if (previousRunId === undefined)
|
|
38
35
|
return undefined;
|
|
@@ -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 = []
|
|
1788
|
-
return publishDeclaredSeatArtifacts(admitted, roleOutcome, coordinates, entries
|
|
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
|
|
1873
|
+
* Seat evidence stays on the artifact face.
|
|
1875
1874
|
*/
|
|
1876
|
-
async function settleSeat(admitted, authority, scope
|
|
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
|
|
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,
|
|
1898
|
-
return settleSeat(admitted, authority, scope
|
|
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,
|
|
1905
|
-
const settled = await settleSeat(admitted, authority, scope
|
|
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
|
|
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
|
|
2167
|
-
|
|
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
|
|
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
|
|
99
|
-
|
|
100
|
-
|
|
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,
|
|
112
|
+
export function admittedSeatTurnDetails(admitted, home, host) {
|
|
105
113
|
return {
|
|
106
114
|
activation: activationForAdmitted(admitted),
|
|
107
|
-
methods: methodBindings(admitted,
|
|
115
|
+
methods: methodBindings(admitted, home, host),
|
|
108
116
|
};
|
|
109
117
|
}
|
|
@@ -274,7 +274,10 @@ async function summonPublicRole(options) {
|
|
|
274
274
|
result = stepped.ok;
|
|
275
275
|
}
|
|
276
276
|
const stderr = captured?.stderrText();
|
|
277
|
-
const runDirectory = result.
|
|
277
|
+
const runDirectory = result.terminal !== void 0 && result.terminal.roleOutcome.role !== options.role && typeof result.terminal.runId === "string" ? await (await import("./public-cli/run-lifecycle.js")).findRunDirectoryById(
|
|
278
|
+
home,
|
|
279
|
+
result.terminal.runId
|
|
280
|
+
) : result.admitted?.runDirectory;
|
|
278
281
|
return {
|
|
279
282
|
exitCode: result.exitCode,
|
|
280
283
|
...result.terminal === void 0 ? {} : { terminal: result.terminal },
|
|
@@ -478,8 +481,10 @@ async function summonGateOfficer(options) {
|
|
|
478
481
|
`countersign gate summon requires parent runId from sourceRunDirectory: ${options.sourceRunDirectory}`
|
|
479
482
|
);
|
|
480
483
|
}
|
|
481
|
-
const { readBoardTicketNumber } = await import("./run-ticket-number.js");
|
|
484
|
+
const { isSafePositiveTicketNumber, readBoardTicketNumber } = await import("./run-ticket-number.js");
|
|
482
485
|
const parentTicket = await readBoardTicketNumber(options.sourceRunDirectory);
|
|
486
|
+
const submittedTicket = options.submission !== null && typeof options.submission === "object" && !Array.isArray(options.submission) ? options.submission.ticketNumber : void 0;
|
|
487
|
+
const courtTicket = isSafePositiveTicketNumber(submittedTicket) ? submittedTicket : parentTicket;
|
|
483
488
|
const instruction = options.reask ?? gateReviewInstruction ?? "";
|
|
484
489
|
return summonPublicRole({
|
|
485
490
|
role: options.officer,
|
|
@@ -487,7 +492,7 @@ async function summonGateOfficer(options) {
|
|
|
487
492
|
...common,
|
|
488
493
|
correlationId,
|
|
489
494
|
parentRunPath: options.sourceRunDirectory,
|
|
490
|
-
...
|
|
495
|
+
...courtTicket === void 0 ? {} : { boundTicketNumber: courtTicket }
|
|
491
496
|
});
|
|
492
497
|
}
|
|
493
498
|
return summonPublicRole({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akagilnc/pi-workflow-roles",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5063",
|
|
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",
|
|
@@ -34,6 +36,8 @@
|
|
|
34
36
|
"schemas",
|
|
35
37
|
"packets",
|
|
36
38
|
"resources",
|
|
39
|
+
"!resources/methods",
|
|
40
|
+
"!resources/methods/**",
|
|
37
41
|
"README.md",
|
|
38
42
|
"LICENSE",
|
|
39
43
|
"THIRD_PARTY_NOTICES.md",
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# 给事中票面审读方法
|
|
2
|
+
|
|
3
|
+
中书省交卷时,以交卷原文所指的实际 GitHub issue 为审读对象;传召附带的绑定票号只用于绑卷,不替中书省决定票号。先在当前项目的 GitHub 仓库用宿主已有 CLI 读取该 issue 的现行正文(例如 `gh issue view <票号> --json body`);不得只看中书省交卷文字或本地草稿,就声称已审 GitHub 票面。对照原交卷和实际 issue 正文,按《票面法》审读。
|
|
4
|
+
|
|
5
|
+
中书省以 `converged` 交卷却没有可审的实际 GitHub issue 身份时,封驳退回中书省补齐;不得以无号草稿署票。此类封驳走现有重交通道,不由代码按回执形状拒收。issue 不存在或正文读取失败时,如实说明现场失败,不把未读到的票面判作已审。交卷与绑卷票号冲突也须说明,不猜测替代票号。
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
|
|
34
34
|
- 认得出本庭对象:`status: completed` 且 `ticketNumber: N`,并交边界。
|
|
35
35
|
- 真无票对象(方案/派单/处置案等):`status: completed` 且 `ticketNumber: null`(或省略)。真无票是合法结果,不入录。
|
|
36
|
+
- 本庭明确要新建票、但 issue 尚未建号:不是认票失败。以 `status: completed`、`ticketNumber: null` 交出已辨明的本案对话边界;起居录先随无号 run 暂存,建号后由既有归卷流程补归该号。不要借用旁票号。
|
|
36
37
|
- 认不出本庭对象是哪一张:`status: escalate` 并写明 `reason`。识别不了就上抛,不得省略票号假装无录,也不得猜一个号。
|
|
37
38
|
- 不得从旁及的他票或任何猜测里挑一个号顶替认不出的身份。
|
|
38
39
|
- 传召文自然会提轮次、决定编号、commit sha、邻票号;你认的是本庭对象,不是文中出现的每一个数字。
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# 中书省票身份与落票方法
|
|
2
|
+
|
|
3
|
+
本方法适用于公开中书省调用。票面范围、审读职责和交卷形状仍以各自法源为准。
|
|
4
|
+
|
|
5
|
+
## 先辨票,再改票
|
|
6
|
+
|
|
7
|
+
调用者可以给票号,也可以不给。给了票号,先读取并核对该 issue,再在原 issue 上更新票面;不要另建一票。没有给票号,不等于新票:先结合本次对话、本票起居录和当前 GitHub 仓库中的 issue 判断是否已有对应票。找到已有票就更新那张;只有确认没有对应票,才在当前仓库创建 issue。不得仅凭内容相似就认定已有票,也不得因没找到就忽略搜索范围或不确定性。
|
|
8
|
+
|
|
9
|
+
票面改定后,应将实际要执行的正文落到对应 GitHub issue。不能确认已有票还是新票、无法读取或更新目标 issue,或创建 issue 失败时,不得把草稿当成已落票结果送庭;可上呈或重交,并说明现场观察到的真实失败原因。若信息不足以区分多个候选 issue,可上呈请裁定,不猜票号、不另建重复票。
|
|
10
|
+
|
|
11
|
+
## 落地后送庭
|
|
12
|
+
|
|
13
|
+
只有确认目标 issue 存在且正文已更新为本票最终票面后,才以 `converged` 交卷,并携带该 issue 的实际票号。沿用既有交卷闸,将交卷原文交给给事中审这张有票号 issue;不以无号草稿替代 issue 审读。不另造传召或记账机制。
|
|
14
|
+
|
|
15
|
+
执行 GitHub 操作时使用当前宿主实际提供的 CLI / 能力;不在包内另造 GitHub 适配层。记录足以核对身份和落地结果的证据,不把模型自报冒充为现场观察。
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { chmod, copyFile,
|
|
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
|
-
|
|
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:
|
|
542
|
+
stdin: prompt,
|
|
564
543
|
...(abortSignal === undefined ? {} : { signal: abortSignal }),
|
|
565
544
|
...(request.timeoutMs === undefined ? {} : { timeoutMs: request.timeoutMs }),
|
|
566
545
|
onStdoutLine(line) {
|
package/src/host-contracts.ts
CHANGED
|
@@ -74,7 +74,7 @@ export class ExplicitInternalActivationError extends Error {
|
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
/**
|
|
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:
|