persona-harness 0.8.36 → 0.8.38

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 (28) hide show
  1. package/README.md +16 -0
  2. package/dist/context-external-validation/context-external-validation-parser.d.ts +3 -0
  3. package/dist/context-external-validation/context-external-validation-parser.js +251 -0
  4. package/dist/context-external-validation/context-external-validation-parser.js.map +1 -0
  5. package/dist/context-external-validation/context-external-validation-types.d.ts +77 -0
  6. package/dist/context-external-validation/context-external-validation-types.js +12 -0
  7. package/dist/context-external-validation/context-external-validation-types.js.map +1 -0
  8. package/dist/context-external-validation/context-external-validation.d.ts +2 -0
  9. package/dist/context-external-validation/context-external-validation.js +56 -0
  10. package/dist/context-external-validation/context-external-validation.js.map +1 -0
  11. package/dist/context-external-validation/index.d.ts +4 -0
  12. package/dist/context-external-validation/index.js +4 -0
  13. package/dist/context-external-validation/index.js.map +1 -0
  14. package/dist/context-external-validation.d.ts +1 -0
  15. package/dist/context-external-validation.js +2 -0
  16. package/dist/context-external-validation.js.map +1 -0
  17. package/docs/current/README.md +2 -0
  18. package/docs/current/canonical-docs-index.md +2 -0
  19. package/docs/current/context-contributor-map.json +89 -0
  20. package/docs/current/context-external-validation-status.json +7 -0
  21. package/docs/current/context-external-validation.md +91 -0
  22. package/docs/current/context-program-status.md +68 -23
  23. package/docs/current/docs-inventory.md +3 -0
  24. package/docs/current/release/consumer-authority-current-acceptance.json +1 -1
  25. package/docs/current/release/v0.8.37-release-notes.md +38 -0
  26. package/docs/current/release/v0.8.38-release-notes.md +38 -0
  27. package/package.json +7 -3
  28. package/packages/shared-skills/package.json +1 -1
package/README.md CHANGED
@@ -95,6 +95,22 @@ Persona Harness exposes two deliberately separate tracks:
95
95
  OpenCode plugin registered, it delivers one bounded Context block only after
96
96
  a safe observed file target. It grants no completion authority.
97
97
 
98
+ ### Context Boundary
99
+
100
+ - **Activation:** `context.enabled` is explicit and `default-off`; it does not
101
+ inherit broad runtime guidance switches.
102
+ - **Authority:** Context is `non-authoritative`: it cannot grant completion or
103
+ verification authority.
104
+ - **Isolation:** Context-only paths do not execute project commands or contact
105
+ GitHub/network.
106
+ - **Host:** OpenCode is the only implemented delivery adapter; live host
107
+ delivery remains a separate, unobserved boundary.
108
+ - **Evidence:** Context usefulness remains `INCONCLUSIVE` until independent
109
+ external evidence exists.
110
+ - **Product focus:** the productized workflow focus is Java/Spring. The
111
+ TypeScript reference implementation and fixtures support this experimental
112
+ Context boundary; they are not a TypeScript code-quality claim.
113
+
98
114
  Context configuration is separate from legacy runtime guidance switches. A
99
115
  missing block stays disabled. An explicit `context.enabled` setting controls
100
116
  only the targeted Context adapter; it does not enable legacy runtime guidance,
@@ -0,0 +1,3 @@
1
+ import type { ContextExternalValidationProtocol, ContextExternalValidationStatus } from "./context-external-validation-types.js";
2
+ export declare function parseContextExternalValidationProtocol(value: unknown): ContextExternalValidationProtocol | undefined;
3
+ export declare function parseContextExternalValidationStatus(value: unknown): ContextExternalValidationStatus | undefined;
@@ -0,0 +1,251 @@
1
+ import { CONTEXT_EXTERNAL_VALIDATION_INITIAL_STATUS, CONTEXT_EXTERNAL_VALIDATION_PROTOCOL_SCHEMA, CONTEXT_EXTERNAL_VALIDATION_STATUS_SCHEMA, } from "./context-external-validation-types.js";
2
+ const CANDIDATE_KEYS = ["commit", "packageVersion", "tarSha256"];
3
+ const PARTICIPANT_KEYS = ["id", "relationship"];
4
+ const PROTOCOL_KEYS = ["candidate", "cohort", "interventionPolicy", "maximumMinutesPerStart", "schemaVersion", "taskDigest", "tokenReference"];
5
+ const STATUS_KEYS = ["observations", "productVerdict", "protocol", "schemaVersion", "status"];
6
+ const OBSERVATION_KEYS = [
7
+ "candidate",
8
+ "conflictResolution",
9
+ "contradictionIncreased",
10
+ "correctionReduced",
11
+ "durationMinutes",
12
+ "intervention",
13
+ "outcome",
14
+ "overreachIncreased",
15
+ "participantId",
16
+ "policySurvived",
17
+ "startState",
18
+ "taskDigest",
19
+ "taskRegressed",
20
+ "tokenOverheadPermille",
21
+ ];
22
+ const MINIMUM_COHORT_SIZE = 3;
23
+ const MAXIMUM_COHORT_SIZE = 5;
24
+ const MAXIMUM_MINUTES_PER_START = 240;
25
+ const MAXIMUM_RECORDED_TOKEN_OVERHEAD_PERMILLE = 10_000;
26
+ export function parseContextExternalValidationProtocol(value) {
27
+ if (!isRecord(value) || !hasExactKeys(value, PROTOCOL_KEYS) || value.schemaVersion !== CONTEXT_EXTERNAL_VALIDATION_PROTOCOL_SCHEMA)
28
+ return undefined;
29
+ const candidate = parseCandidate(value.candidate);
30
+ const cohort = parseCohort(value.cohort);
31
+ if (candidate === undefined || cohort === undefined || !isSha256(value.taskDigest))
32
+ return undefined;
33
+ if (value.tokenReference !== "same-task-context-off")
34
+ return undefined;
35
+ if (value.interventionPolicy !== "none" && value.interventionPolicy !== "clarification-only")
36
+ return undefined;
37
+ if (!isBoundedInteger(value.maximumMinutesPerStart, 1, MAXIMUM_MINUTES_PER_START))
38
+ return undefined;
39
+ return {
40
+ candidate,
41
+ cohort,
42
+ interventionPolicy: value.interventionPolicy,
43
+ maximumMinutesPerStart: value.maximumMinutesPerStart,
44
+ schemaVersion: CONTEXT_EXTERNAL_VALIDATION_PROTOCOL_SCHEMA,
45
+ taskDigest: value.taskDigest,
46
+ tokenReference: "same-task-context-off",
47
+ };
48
+ }
49
+ export function parseContextExternalValidationStatus(value) {
50
+ if (!isRecord(value) || !hasExactKeys(value, STATUS_KEYS) || value.schemaVersion !== CONTEXT_EXTERNAL_VALIDATION_STATUS_SCHEMA)
51
+ return undefined;
52
+ if (value.status === "not-started") {
53
+ if (value.protocol !== null || !isEmptyArray(value.observations) || value.productVerdict !== "INCONCLUSIVE")
54
+ return undefined;
55
+ return CONTEXT_EXTERNAL_VALIDATION_INITIAL_STATUS;
56
+ }
57
+ const protocol = parseContextExternalValidationProtocol(value.protocol);
58
+ const observations = parseObservations(value.observations);
59
+ if (protocol === undefined || observations === undefined || !observationsMatchProtocol(observations, protocol))
60
+ return undefined;
61
+ if (value.status === "preregistered") {
62
+ if (!isEmptyArray(observations) || value.productVerdict !== "INCONCLUSIVE")
63
+ return undefined;
64
+ return { observations, productVerdict: "INCONCLUSIVE", protocol, schemaVersion: CONTEXT_EXTERNAL_VALIDATION_STATUS_SCHEMA, status: "preregistered" };
65
+ }
66
+ if (value.status === "observing") {
67
+ if (observations.length === 0 || observations.length >= protocol.cohort.length || value.productVerdict !== "INCONCLUSIVE")
68
+ return undefined;
69
+ return { observations, productVerdict: "INCONCLUSIVE", protocol, schemaVersion: CONTEXT_EXTERNAL_VALIDATION_STATUS_SCHEMA, status: "observing" };
70
+ }
71
+ if (value.status !== "completed" || !hasCompleteDenominator(observations, protocol.cohort))
72
+ return undefined;
73
+ if (value.productVerdict !== "PRODUCT_GO" && value.productVerdict !== "PRODUCT_NO_GO")
74
+ return undefined;
75
+ return { observations, productVerdict: value.productVerdict, protocol, schemaVersion: CONTEXT_EXTERNAL_VALIDATION_STATUS_SCHEMA, status: "completed" };
76
+ }
77
+ function parseCandidate(value) {
78
+ if (!isRecord(value) || !hasExactKeys(value, CANDIDATE_KEYS))
79
+ return undefined;
80
+ if (!isCommit(value.commit) || !isPackageVersion(value.packageVersion) || !isSha256(value.tarSha256))
81
+ return undefined;
82
+ return { commit: value.commit, packageVersion: value.packageVersion, tarSha256: value.tarSha256 };
83
+ }
84
+ function parseCohort(value) {
85
+ if (!Array.isArray(value) || value.length < MINIMUM_COHORT_SIZE || value.length > MAXIMUM_COHORT_SIZE)
86
+ return undefined;
87
+ const cohort = [];
88
+ for (const entry of value) {
89
+ const participant = parseParticipant(entry);
90
+ if (participant === undefined)
91
+ return undefined;
92
+ cohort.push(participant);
93
+ }
94
+ return isStrictlySortedUnique(cohort.map((participant) => participant.id)) ? cohort : undefined;
95
+ }
96
+ function parseParticipant(value) {
97
+ if (!isRecord(value) || !hasExactKeys(value, PARTICIPANT_KEYS) || !isParticipantId(value.id))
98
+ return undefined;
99
+ if (value.relationship !== "independent" && value.relationship !== "past-collaborator" && value.relationship !== "disclosed-other")
100
+ return undefined;
101
+ return { id: value.id, relationship: value.relationship };
102
+ }
103
+ function parseObservations(value) {
104
+ if (!Array.isArray(value) || value.length > MAXIMUM_COHORT_SIZE)
105
+ return undefined;
106
+ const observations = [];
107
+ for (const entry of value) {
108
+ const observation = parseObservation(entry);
109
+ if (observation === undefined)
110
+ return undefined;
111
+ observations.push(observation);
112
+ }
113
+ return hasUnique(observations.map((observation) => observation.participantId)) ? observations : undefined;
114
+ }
115
+ function parseObservation(value) {
116
+ if (!isRecord(value) || !hasExactKeys(value, OBSERVATION_KEYS))
117
+ return undefined;
118
+ const candidate = parseCandidate(value.candidate);
119
+ const participantId = value.participantId;
120
+ const taskDigest = value.taskDigest;
121
+ if (candidate === undefined || !isParticipantId(participantId) || !isSha256(taskDigest))
122
+ return undefined;
123
+ const identity = { candidate, participantId, taskDigest };
124
+ if (value.startState === "accepted-start")
125
+ return parseAcceptedStart(value, identity);
126
+ if (value.startState === "declined-before-start" || value.startState === "withdrawn-before-start") {
127
+ return parseUnstartedObservation(value, identity, value.startState);
128
+ }
129
+ return undefined;
130
+ }
131
+ function parseAcceptedStart(value, identity) {
132
+ const outcome = value.outcome;
133
+ const conflictResolution = value.conflictResolution;
134
+ const contradictionIncreased = value.contradictionIncreased;
135
+ const correctionReduced = value.correctionReduced;
136
+ const durationMinutes = value.durationMinutes;
137
+ const intervention = value.intervention;
138
+ const overreachIncreased = value.overreachIncreased;
139
+ const policySurvived = value.policySurvived;
140
+ const taskRegressed = value.taskRegressed;
141
+ const tokenOverheadPermille = value.tokenOverheadPermille;
142
+ if ((outcome !== "completed" && outcome !== "not-completed") || (conflictResolution !== "accurate" && conflictResolution !== "inaccurate"))
143
+ return undefined;
144
+ if (!isBoolean(contradictionIncreased) || !isBoolean(correctionReduced) || !isBoundedInteger(durationMinutes, 1, MAXIMUM_MINUTES_PER_START))
145
+ return undefined;
146
+ if (!isBoolean(overreachIncreased) || !isBoolean(policySurvived) || !isBoolean(taskRegressed))
147
+ return undefined;
148
+ if (!isBoundedInteger(tokenOverheadPermille, 0, MAXIMUM_RECORDED_TOKEN_OVERHEAD_PERMILLE))
149
+ return undefined;
150
+ if (intervention !== "none" && intervention !== "declared-clarification")
151
+ return undefined;
152
+ return {
153
+ candidate: identity.candidate,
154
+ conflictResolution,
155
+ contradictionIncreased,
156
+ correctionReduced,
157
+ durationMinutes,
158
+ intervention,
159
+ overreachIncreased,
160
+ outcome,
161
+ participantId: identity.participantId,
162
+ policySurvived,
163
+ startState: "accepted-start",
164
+ taskDigest: identity.taskDigest,
165
+ taskRegressed,
166
+ tokenOverheadPermille,
167
+ };
168
+ }
169
+ function parseUnstartedObservation(value, identity, startState) {
170
+ if (value.outcome !== "not-observed" || value.conflictResolution !== "not-observed" || value.intervention !== "none")
171
+ return undefined;
172
+ if (value.contradictionIncreased !== null || value.correctionReduced !== null || value.durationMinutes !== null || value.overreachIncreased !== null)
173
+ return undefined;
174
+ if (value.policySurvived !== null || value.taskRegressed !== null || value.tokenOverheadPermille !== null)
175
+ return undefined;
176
+ return {
177
+ candidate: identity.candidate,
178
+ conflictResolution: "not-observed",
179
+ contradictionIncreased: null,
180
+ correctionReduced: null,
181
+ durationMinutes: null,
182
+ intervention: "none",
183
+ overreachIncreased: null,
184
+ outcome: "not-observed",
185
+ participantId: identity.participantId,
186
+ policySurvived: null,
187
+ startState,
188
+ taskDigest: identity.taskDigest,
189
+ taskRegressed: null,
190
+ tokenOverheadPermille: null,
191
+ };
192
+ }
193
+ function observationsMatchProtocol(observations, protocol) {
194
+ return observations.every((observation) => {
195
+ if (!sameCandidate(observation.candidate, protocol.candidate) || observation.taskDigest !== protocol.taskDigest)
196
+ return false;
197
+ if (!protocol.cohort.some((participant) => participant.id === observation.participantId))
198
+ return false;
199
+ if (observation.startState !== "accepted-start")
200
+ return true;
201
+ if (observation.durationMinutes === null || observation.durationMinutes > protocol.maximumMinutesPerStart)
202
+ return false;
203
+ return protocol.interventionPolicy === "clarification-only" || observation.intervention === "none";
204
+ });
205
+ }
206
+ function hasCompleteDenominator(observations, cohort) {
207
+ return observations.length === cohort.length && observations.every((observation, index) => observation.participantId === cohort[index]?.id);
208
+ }
209
+ function sameCandidate(left, right) {
210
+ return left.commit === right.commit && left.packageVersion === right.packageVersion && left.tarSha256 === right.tarSha256;
211
+ }
212
+ function hasExactKeys(value, keys) {
213
+ return Object.keys(value).length === keys.length && Object.keys(value).every((key) => keys.includes(key));
214
+ }
215
+ function isRecord(value) {
216
+ return typeof value === "object" && value !== null && !Array.isArray(value);
217
+ }
218
+ function isEmptyArray(value) {
219
+ return Array.isArray(value) && value.length === 0;
220
+ }
221
+ function isStrictlySortedUnique(values) {
222
+ let previous;
223
+ for (const value of values) {
224
+ if (previous !== undefined && previous >= value)
225
+ return false;
226
+ previous = value;
227
+ }
228
+ return true;
229
+ }
230
+ function hasUnique(values) {
231
+ return new Set(values).size === values.length;
232
+ }
233
+ function isCommit(value) {
234
+ return typeof value === "string" && /^[0-9a-f]{40}$/u.test(value);
235
+ }
236
+ function isPackageVersion(value) {
237
+ return typeof value === "string" && /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u.test(value);
238
+ }
239
+ function isSha256(value) {
240
+ return typeof value === "string" && /^[0-9a-f]{64}$/u.test(value);
241
+ }
242
+ function isParticipantId(value) {
243
+ return typeof value === "string" && /^P-(?:0[1-9]|[1-9][0-9])$/u.test(value);
244
+ }
245
+ function isBoundedInteger(value, minimum, maximum) {
246
+ return typeof value === "number" && Number.isInteger(value) && value >= minimum && value <= maximum;
247
+ }
248
+ function isBoolean(value) {
249
+ return typeof value === "boolean";
250
+ }
251
+ //# sourceMappingURL=context-external-validation-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-external-validation-parser.js","sourceRoot":"","sources":["../../src/context-external-validation/context-external-validation-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0CAA0C,EAC1C,2CAA2C,EAC3C,yCAAyC,GAC1C,MAAM,wCAAwC,CAAA;AAS/C,MAAM,cAAc,GAAG,CAAC,QAAQ,EAAE,gBAAgB,EAAE,WAAW,CAAU,CAAA;AACzE,MAAM,gBAAgB,GAAG,CAAC,IAAI,EAAE,cAAc,CAAU,CAAA;AACxD,MAAM,aAAa,GAAG,CAAC,WAAW,EAAE,QAAQ,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,CAAU,CAAA;AACvJ,MAAM,WAAW,GAAG,CAAC,cAAc,EAAE,gBAAgB,EAAE,UAAU,EAAE,eAAe,EAAE,QAAQ,CAAU,CAAA;AACtG,MAAM,gBAAgB,GAAG;IACvB,WAAW;IACX,oBAAoB;IACpB,wBAAwB;IACxB,mBAAmB;IACnB,iBAAiB;IACjB,cAAc;IACd,SAAS;IACT,oBAAoB;IACpB,eAAe;IACf,gBAAgB;IAChB,YAAY;IACZ,YAAY;IACZ,eAAe;IACf,uBAAuB;CACf,CAAA;AAEV,MAAM,mBAAmB,GAAG,CAAC,CAAA;AAC7B,MAAM,mBAAmB,GAAG,CAAC,CAAA;AAC7B,MAAM,yBAAyB,GAAG,GAAG,CAAA;AACrC,MAAM,wCAAwC,GAAG,MAAM,CAAA;AAQvD,MAAM,UAAU,sCAAsC,CAAC,KAAc;IACnE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,aAAa,CAAC,IAAI,KAAK,CAAC,aAAa,KAAK,2CAA2C;QAAE,OAAO,SAAS,CAAA;IAEpJ,MAAM,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;IACjD,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IACxC,IAAI,SAAS,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC;QAAE,OAAO,SAAS,CAAA;IACpG,IAAI,KAAK,CAAC,cAAc,KAAK,uBAAuB;QAAE,OAAO,SAAS,CAAA;IACtE,IAAI,KAAK,CAAC,kBAAkB,KAAK,MAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,oBAAoB;QAAE,OAAO,SAAS,CAAA;IAC9G,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,sBAAsB,EAAE,CAAC,EAAE,yBAAyB,CAAC;QAAE,OAAO,SAAS,CAAA;IAEnG,OAAO;QACL,SAAS;QACT,MAAM;QACN,kBAAkB,EAAE,KAAK,CAAC,kBAAkB;QAC5C,sBAAsB,EAAE,KAAK,CAAC,sBAAsB;QACpD,aAAa,EAAE,2CAA2C;QAC1D,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,cAAc,EAAE,uBAAuB;KACxC,CAAA;AACH,CAAC;AAED,MAAM,UAAU,oCAAoC,CAAC,KAAc;IACjE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,WAAW,CAAC,IAAI,KAAK,CAAC,aAAa,KAAK,yCAAyC;QAAE,OAAO,SAAS,CAAA;IAEhJ,IAAI,KAAK,CAAC,MAAM,KAAK,aAAa,EAAE,CAAC;QACnC,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,KAAK,CAAC,cAAc,KAAK,cAAc;YAAE,OAAO,SAAS,CAAA;QAC7H,OAAO,0CAA0C,CAAA;IACnD,CAAC;IAED,MAAM,QAAQ,GAAG,sCAAsC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;IACvE,MAAM,YAAY,GAAG,iBAAiB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IAC1D,IAAI,QAAQ,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS,IAAI,CAAC,yBAAyB,CAAC,YAAY,EAAE,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAA;IAEhI,IAAI,KAAK,CAAC,MAAM,KAAK,eAAe,EAAE,CAAC;QACrC,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,IAAI,KAAK,CAAC,cAAc,KAAK,cAAc;YAAE,OAAO,SAAS,CAAA;QAC5F,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,aAAa,EAAE,yCAAyC,EAAE,MAAM,EAAE,eAAe,EAAE,CAAA;IACtJ,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;QACjC,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,IAAI,YAAY,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,cAAc;YAAE,OAAO,SAAS,CAAA;QAC3I,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,aAAa,EAAE,yCAAyC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAA;IAClJ,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,sBAAsB,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,SAAS,CAAA;IAC5G,IAAI,KAAK,CAAC,cAAc,KAAK,YAAY,IAAI,KAAK,CAAC,cAAc,KAAK,eAAe;QAAE,OAAO,SAAS,CAAA;IACvG,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,KAAK,CAAC,cAAc,EAAE,QAAQ,EAAE,aAAa,EAAE,yCAAyC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAA;AACxJ,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACpC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC;QAAE,OAAO,SAAS,CAAA;IAC9E,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC;QAAE,OAAO,SAAS,CAAA;IACtH,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,CAAC,cAAc,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAA;AACnG,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,mBAAmB,IAAI,KAAK,CAAC,MAAM,GAAG,mBAAmB;QAAE,OAAO,SAAS,CAAA;IAEvH,MAAM,MAAM,GAA2C,EAAE,CAAA;IACzD,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,WAAW,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAA;QAC3C,IAAI,WAAW,KAAK,SAAS;YAAE,OAAO,SAAS,CAAA;QAC/C,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IAC1B,CAAC;IAED,OAAO,sBAAsB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAA;AACjG,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc;IACtC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,gBAAgB,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QAAE,OAAO,SAAS,CAAA;IAC9G,IAAI,KAAK,CAAC,YAAY,KAAK,aAAa,IAAI,KAAK,CAAC,YAAY,KAAK,mBAAmB,IAAI,KAAK,CAAC,YAAY,KAAK,iBAAiB;QAAE,OAAO,SAAS,CAAA;IACpJ,OAAO,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY,EAAE,CAAA;AAC3D,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAc;IACvC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,mBAAmB;QAAE,OAAO,SAAS,CAAA;IAEjF,MAAM,YAAY,GAA2C,EAAE,CAAA;IAC/D,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,WAAW,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAA;QAC3C,IAAI,WAAW,KAAK,SAAS;YAAE,OAAO,SAAS,CAAA;QAC/C,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IAChC,CAAC;IAED,OAAO,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAA;AAC3G,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc;IACtC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,gBAAgB,CAAC;QAAE,OAAO,SAAS,CAAA;IAEhF,MAAM,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;IACjD,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,CAAA;IACzC,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAA;IACnC,IAAI,SAAS,KAAK,SAAS,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,SAAS,CAAA;IACzG,MAAM,QAAQ,GAA8B,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,CAAA;IAEpF,IAAI,KAAK,CAAC,UAAU,KAAK,gBAAgB;QAAE,OAAO,kBAAkB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;IACrF,IAAI,KAAK,CAAC,UAAU,KAAK,uBAAuB,IAAI,KAAK,CAAC,UAAU,KAAK,wBAAwB,EAAE,CAAC;QAClG,OAAO,yBAAyB,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,CAAA;IACrE,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAS,kBAAkB,CACzB,KAA8B,EAC9B,QAAmC;IAEnC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAA;IAC7B,MAAM,kBAAkB,GAAG,KAAK,CAAC,kBAAkB,CAAA;IACnD,MAAM,sBAAsB,GAAG,KAAK,CAAC,sBAAsB,CAAA;IAC3D,MAAM,iBAAiB,GAAG,KAAK,CAAC,iBAAiB,CAAA;IACjD,MAAM,eAAe,GAAG,KAAK,CAAC,eAAe,CAAA;IAC7C,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAA;IACvC,MAAM,kBAAkB,GAAG,KAAK,CAAC,kBAAkB,CAAA;IACnD,MAAM,cAAc,GAAG,KAAK,CAAC,cAAc,CAAA;IAC3C,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,CAAA;IACzC,MAAM,qBAAqB,GAAG,KAAK,CAAC,qBAAqB,CAAA;IACzD,IAAI,CAAC,OAAO,KAAK,WAAW,IAAI,OAAO,KAAK,eAAe,CAAC,IAAI,CAAC,kBAAkB,KAAK,UAAU,IAAI,kBAAkB,KAAK,YAAY,CAAC;QAAE,OAAO,SAAS,CAAA;IAC5J,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,IAAI,CAAC,gBAAgB,CAAC,eAAe,EAAE,CAAC,EAAE,yBAAyB,CAAC;QAAE,OAAO,SAAS,CAAA;IAC7J,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC;QAAE,OAAO,SAAS,CAAA;IAC/G,IAAI,CAAC,gBAAgB,CAAC,qBAAqB,EAAE,CAAC,EAAE,wCAAwC,CAAC;QAAE,OAAO,SAAS,CAAA;IAC3G,IAAI,YAAY,KAAK,MAAM,IAAI,YAAY,KAAK,wBAAwB;QAAE,OAAO,SAAS,CAAA;IAE1F,OAAO;QACL,SAAS,EAAE,QAAQ,CAAC,SAAS;QAC7B,kBAAkB;QAClB,sBAAsB;QACtB,iBAAiB;QACjB,eAAe;QACf,YAAY;QACZ,kBAAkB;QAClB,OAAO;QACP,aAAa,EAAE,QAAQ,CAAC,aAAa;QACrC,cAAc;QACd,UAAU,EAAE,gBAAgB;QAC5B,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,aAAa;QACb,qBAAqB;KACtB,CAAA;AACH,CAAC;AAED,SAAS,yBAAyB,CAChC,KAA8B,EAC9B,QAAmC,EACnC,UAA8D;IAE9D,IAAI,KAAK,CAAC,OAAO,KAAK,cAAc,IAAI,KAAK,CAAC,kBAAkB,KAAK,cAAc,IAAI,KAAK,CAAC,YAAY,KAAK,MAAM;QAAE,OAAO,SAAS,CAAA;IACtI,IAAI,KAAK,CAAC,sBAAsB,KAAK,IAAI,IAAI,KAAK,CAAC,iBAAiB,KAAK,IAAI,IAAI,KAAK,CAAC,eAAe,KAAK,IAAI,IAAI,KAAK,CAAC,kBAAkB,KAAK,IAAI;QAAE,OAAO,SAAS,CAAA;IACtK,IAAI,KAAK,CAAC,cAAc,KAAK,IAAI,IAAI,KAAK,CAAC,aAAa,KAAK,IAAI,IAAI,KAAK,CAAC,qBAAqB,KAAK,IAAI;QAAE,OAAO,SAAS,CAAA;IAE3H,OAAO;QACL,SAAS,EAAE,QAAQ,CAAC,SAAS;QAC7B,kBAAkB,EAAE,cAAc;QAClC,sBAAsB,EAAE,IAAI;QAC5B,iBAAiB,EAAE,IAAI;QACvB,eAAe,EAAE,IAAI;QACrB,YAAY,EAAE,MAAM;QACpB,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,cAAc;QACvB,aAAa,EAAE,QAAQ,CAAC,aAAa;QACrC,cAAc,EAAE,IAAI;QACpB,UAAU;QACV,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,aAAa,EAAE,IAAI;QACnB,qBAAqB,EAAE,IAAI;KAC5B,CAAA;AACH,CAAC;AAED,SAAS,yBAAyB,CAAC,YAA6D,EAAE,QAA2C;IAC3I,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,EAAE;QACxC,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC,IAAI,WAAW,CAAC,UAAU,KAAK,QAAQ,CAAC,UAAU;YAAE,OAAO,KAAK,CAAA;QAC7H,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,KAAK,WAAW,CAAC,aAAa,CAAC;YAAE,OAAO,KAAK,CAAA;QACtG,IAAI,WAAW,CAAC,UAAU,KAAK,gBAAgB;YAAE,OAAO,IAAI,CAAA;QAC5D,IAAI,WAAW,CAAC,eAAe,KAAK,IAAI,IAAI,WAAW,CAAC,eAAe,GAAG,QAAQ,CAAC,sBAAsB;YAAE,OAAO,KAAK,CAAA;QACvH,OAAO,QAAQ,CAAC,kBAAkB,KAAK,oBAAoB,IAAI,WAAW,CAAC,YAAY,KAAK,MAAM,CAAA;IACpG,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,sBAAsB,CAC7B,YAA6D,EAC7D,MAAuD;IAEvD,OAAO,YAAY,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,aAAa,KAAK,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAA;AAC7I,CAAC;AAED,SAAS,aAAa,CAAC,IAAwC,EAAE,KAAyC;IACxG,OAAO,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,cAAc,KAAK,KAAK,CAAC,cAAc,IAAI,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,CAAA;AAC3H,CAAC;AAED,SAAS,YAAY,CAAC,KAA8B,EAAE,IAAuB;IAC3E,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAA;AAC3G,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAC7E,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,CAAA;AACnD,CAAC;AAED,SAAS,sBAAsB,CAAC,MAAyB;IACvD,IAAI,QAA4B,CAAA;IAChC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,IAAI,KAAK;YAAE,OAAO,KAAK,CAAA;QAC7D,QAAQ,GAAG,KAAK,CAAA;IAClB,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,SAAS,CAAC,MAAyB;IAC1C,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,CAAA;AAC/C,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AACnE,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc;IACtC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,sCAAsC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AACxF,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AACnE,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,4BAA4B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AAC9E,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc,EAAE,OAAe,EAAE,OAAe;IACxE,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,OAAO,IAAI,KAAK,IAAI,OAAO,CAAA;AACrG,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,OAAO,KAAK,KAAK,SAAS,CAAA;AACnC,CAAC"}
@@ -0,0 +1,77 @@
1
+ export declare const CONTEXT_EXTERNAL_VALIDATION_PROTOCOL_SCHEMA: "persona-context-external-validation-protocol.1";
2
+ export declare const CONTEXT_EXTERNAL_VALIDATION_STATUS_SCHEMA: "persona-context-external-validation-status.1";
3
+ export declare const CONTEXT_EXTERNAL_VALIDATION_RESULT_SCHEMA: "persona-context-external-validation-result.1";
4
+ export type ContextExternalValidationCandidate = {
5
+ readonly commit: string;
6
+ readonly packageVersion: string;
7
+ readonly tarSha256: string;
8
+ };
9
+ export type ContextExternalValidationParticipant = {
10
+ readonly id: string;
11
+ readonly relationship: "independent" | "past-collaborator" | "disclosed-other";
12
+ };
13
+ export type ContextExternalValidationProtocol = {
14
+ readonly candidate: ContextExternalValidationCandidate;
15
+ readonly cohort: readonly ContextExternalValidationParticipant[];
16
+ readonly interventionPolicy: "none" | "clarification-only";
17
+ readonly maximumMinutesPerStart: number;
18
+ readonly schemaVersion: typeof CONTEXT_EXTERNAL_VALIDATION_PROTOCOL_SCHEMA;
19
+ readonly taskDigest: string;
20
+ readonly tokenReference: "same-task-context-off";
21
+ };
22
+ export type ContextExternalValidationObservation = {
23
+ readonly candidate: ContextExternalValidationCandidate;
24
+ readonly conflictResolution: "accurate" | "inaccurate" | "not-observed";
25
+ readonly contradictionIncreased: boolean | null;
26
+ readonly correctionReduced: boolean | null;
27
+ readonly durationMinutes: number | null;
28
+ readonly intervention: "none" | "declared-clarification";
29
+ readonly overreachIncreased: boolean | null;
30
+ readonly outcome: "completed" | "not-completed" | "not-observed";
31
+ readonly participantId: string;
32
+ readonly policySurvived: boolean | null;
33
+ readonly startState: "accepted-start" | "declined-before-start" | "withdrawn-before-start";
34
+ readonly taskDigest: string;
35
+ readonly taskRegressed: boolean | null;
36
+ readonly tokenOverheadPermille: number | null;
37
+ };
38
+ export type ContextExternalValidationProductVerdict = "INCONCLUSIVE" | "PRODUCT_GO" | "PRODUCT_NO_GO";
39
+ export type ContextExternalValidationStatus = {
40
+ readonly observations: readonly [];
41
+ readonly productVerdict: "INCONCLUSIVE";
42
+ readonly protocol: null;
43
+ readonly schemaVersion: typeof CONTEXT_EXTERNAL_VALIDATION_STATUS_SCHEMA;
44
+ readonly status: "not-started";
45
+ } | {
46
+ readonly observations: readonly [];
47
+ readonly productVerdict: "INCONCLUSIVE";
48
+ readonly protocol: ContextExternalValidationProtocol;
49
+ readonly schemaVersion: typeof CONTEXT_EXTERNAL_VALIDATION_STATUS_SCHEMA;
50
+ readonly status: "preregistered";
51
+ } | {
52
+ readonly observations: readonly ContextExternalValidationObservation[];
53
+ readonly productVerdict: "INCONCLUSIVE";
54
+ readonly protocol: ContextExternalValidationProtocol;
55
+ readonly schemaVersion: typeof CONTEXT_EXTERNAL_VALIDATION_STATUS_SCHEMA;
56
+ readonly status: "observing";
57
+ } | {
58
+ readonly observations: readonly ContextExternalValidationObservation[];
59
+ readonly productVerdict: "PRODUCT_GO" | "PRODUCT_NO_GO";
60
+ readonly protocol: ContextExternalValidationProtocol;
61
+ readonly schemaVersion: typeof CONTEXT_EXTERNAL_VALIDATION_STATUS_SCHEMA;
62
+ readonly status: "completed";
63
+ };
64
+ export type ContextExternalValidationResult = {
65
+ readonly code: "context-external-validation-status-invalid" | "context-external-validation-verdict-mismatch";
66
+ readonly schemaVersion: typeof CONTEXT_EXTERNAL_VALIDATION_RESULT_SCHEMA;
67
+ readonly status: "blocked";
68
+ } | {
69
+ readonly acceptedStartCount: number;
70
+ readonly independentStartCount: number;
71
+ readonly observationCount: number;
72
+ readonly phase: ContextExternalValidationStatus["status"];
73
+ readonly productVerdict: ContextExternalValidationProductVerdict;
74
+ readonly schemaVersion: typeof CONTEXT_EXTERNAL_VALIDATION_RESULT_SCHEMA;
75
+ readonly status: "ready";
76
+ };
77
+ export declare const CONTEXT_EXTERNAL_VALIDATION_INITIAL_STATUS: ContextExternalValidationStatus;
@@ -0,0 +1,12 @@
1
+ export const CONTEXT_EXTERNAL_VALIDATION_PROTOCOL_SCHEMA = "persona-context-external-validation-protocol.1";
2
+ export const CONTEXT_EXTERNAL_VALIDATION_STATUS_SCHEMA = "persona-context-external-validation-status.1";
3
+ export const CONTEXT_EXTERNAL_VALIDATION_RESULT_SCHEMA = "persona-context-external-validation-result.1";
4
+ const EMPTY_OBSERVATIONS = [];
5
+ export const CONTEXT_EXTERNAL_VALIDATION_INITIAL_STATUS = Object.freeze({
6
+ observations: EMPTY_OBSERVATIONS,
7
+ productVerdict: "INCONCLUSIVE",
8
+ protocol: null,
9
+ schemaVersion: CONTEXT_EXTERNAL_VALIDATION_STATUS_SCHEMA,
10
+ status: "not-started",
11
+ });
12
+ //# sourceMappingURL=context-external-validation-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-external-validation-types.js","sourceRoot":"","sources":["../../src/context-external-validation/context-external-validation-types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,2CAA2C,GAAG,gDAAyD,CAAA;AACpH,MAAM,CAAC,MAAM,yCAAyC,GAAG,8CAAuD,CAAA;AAChH,MAAM,CAAC,MAAM,yCAAyC,GAAG,8CAAuD,CAAA;AAwFhH,MAAM,kBAAkB,GAAgB,EAAE,CAAA;AAE1C,MAAM,CAAC,MAAM,0CAA0C,GAAoC,MAAM,CAAC,MAAM,CAAC;IACvG,YAAY,EAAE,kBAAkB;IAChC,cAAc,EAAE,cAAc;IAC9B,QAAQ,EAAE,IAAI;IACd,aAAa,EAAE,yCAAyC;IACxD,MAAM,EAAE,aAAa;CACtB,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ import type { ContextExternalValidationResult } from "./context-external-validation-types.js";
2
+ export declare function evaluateContextExternalValidationStatus(value: unknown): ContextExternalValidationResult;
@@ -0,0 +1,56 @@
1
+ import { CONTEXT_EXTERNAL_VALIDATION_RESULT_SCHEMA } from "./context-external-validation-types.js";
2
+ import { parseContextExternalValidationStatus } from "./context-external-validation-parser.js";
3
+ const MINIMUM_INDEPENDENT_STARTS = 3;
4
+ const PRODUCT_GO_TOKEN_OVERHEAD_PERMILLE = 1_300;
5
+ export function evaluateContextExternalValidationStatus(value) {
6
+ const parsed = parseContextExternalValidationStatus(value);
7
+ if (parsed === undefined)
8
+ return blocked("context-external-validation-status-invalid");
9
+ if (parsed.status === "not-started") {
10
+ return {
11
+ acceptedStartCount: 0,
12
+ independentStartCount: 0,
13
+ observationCount: 0,
14
+ phase: "not-started",
15
+ productVerdict: "INCONCLUSIVE",
16
+ schemaVersion: CONTEXT_EXTERNAL_VALIDATION_RESULT_SCHEMA,
17
+ status: "ready",
18
+ };
19
+ }
20
+ const acceptedStarts = parsed.observations.filter((observation) => observation.startState === "accepted-start");
21
+ const independentStartCount = acceptedStarts.filter((observation) => relationshipFor(parsed.protocol.cohort, observation.participantId) === "independent").length;
22
+ const productVerdict = parsed.status === "completed"
23
+ ? calculateCompletedVerdict(parsed.protocol, acceptedStarts, independentStartCount)
24
+ : "INCONCLUSIVE";
25
+ if (parsed.productVerdict !== productVerdict)
26
+ return blocked("context-external-validation-verdict-mismatch");
27
+ return {
28
+ acceptedStartCount: acceptedStarts.length,
29
+ independentStartCount,
30
+ observationCount: parsed.observations.length,
31
+ phase: parsed.status,
32
+ productVerdict,
33
+ schemaVersion: CONTEXT_EXTERNAL_VALIDATION_RESULT_SCHEMA,
34
+ status: "ready",
35
+ };
36
+ }
37
+ function calculateCompletedVerdict(protocol, acceptedStarts, independentStartCount) {
38
+ const positiveOutcomes = acceptedStarts.filter((observation) => observation.correctionReduced === true || observation.policySurvived === true).length;
39
+ const qualifies = independentStartCount >= MINIMUM_INDEPENDENT_STARTS
40
+ && positiveOutcomes >= 2
41
+ && acceptedStarts.every((observation) => observation.outcome === "completed")
42
+ && acceptedStarts.every((observation) => observation.conflictResolution === "accurate")
43
+ && acceptedStarts.every((observation) => observation.contradictionIncreased === false && observation.overreachIncreased === false)
44
+ && acceptedStarts.every((observation) => observation.taskRegressed === false)
45
+ && acceptedStarts.every((observation) => observation.durationMinutes !== null && observation.durationMinutes <= protocol.maximumMinutesPerStart)
46
+ && acceptedStarts.every((observation) => observation.tokenOverheadPermille !== null && observation.tokenOverheadPermille <= PRODUCT_GO_TOKEN_OVERHEAD_PERMILLE)
47
+ && acceptedStarts.every((observation) => observation.intervention === "none");
48
+ return qualifies ? "PRODUCT_GO" : "PRODUCT_NO_GO";
49
+ }
50
+ function relationshipFor(cohort, participantId) {
51
+ return cohort.find((participant) => participant.id === participantId)?.relationship;
52
+ }
53
+ function blocked(code) {
54
+ return { code, schemaVersion: CONTEXT_EXTERNAL_VALIDATION_RESULT_SCHEMA, status: "blocked" };
55
+ }
56
+ //# sourceMappingURL=context-external-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-external-validation.js","sourceRoot":"","sources":["../../src/context-external-validation/context-external-validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { CONTEXT_EXTERNAL_VALIDATION_INITIAL_STATUS, CONTEXT_EXTERNAL_VALIDATION_PROTOCOL_SCHEMA, CONTEXT_EXTERNAL_VALIDATION_RESULT_SCHEMA, CONTEXT_EXTERNAL_VALIDATION_STATUS_SCHEMA, } from "./context-external-validation-types.js";
2
+ export type { ContextExternalValidationCandidate, ContextExternalValidationObservation, ContextExternalValidationParticipant, ContextExternalValidationProductVerdict, ContextExternalValidationProtocol, ContextExternalValidationResult, ContextExternalValidationStatus, } from "./context-external-validation-types.js";
3
+ export { evaluateContextExternalValidationStatus } from "./context-external-validation.js";
4
+ export { parseContextExternalValidationProtocol, parseContextExternalValidationStatus } from "./context-external-validation-parser.js";
@@ -0,0 +1,4 @@
1
+ export { CONTEXT_EXTERNAL_VALIDATION_INITIAL_STATUS, CONTEXT_EXTERNAL_VALIDATION_PROTOCOL_SCHEMA, CONTEXT_EXTERNAL_VALIDATION_RESULT_SCHEMA, CONTEXT_EXTERNAL_VALIDATION_STATUS_SCHEMA, } from "./context-external-validation-types.js";
2
+ export { evaluateContextExternalValidationStatus } from "./context-external-validation.js";
3
+ export { parseContextExternalValidationProtocol, parseContextExternalValidationStatus } from "./context-external-validation-parser.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/context-external-validation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0CAA0C,EAC1C,2CAA2C,EAC3C,yCAAyC,EACzC,yCAAyC,GAC1C,MAAM,wCAAwC,CAAA;AAU/C,OAAO,EAAE,uCAAuC,EAAE,MAAM,kCAAkC,CAAA;AAC1F,OAAO,EAAE,sCAAsC,EAAE,oCAAoC,EAAE,MAAM,yCAAyC,CAAA"}
@@ -0,0 +1 @@
1
+ export * from "./context-external-validation/index.js";
@@ -0,0 +1,2 @@
1
+ export * from "./context-external-validation/index.js";
2
+ //# sourceMappingURL=context-external-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-external-validation.js","sourceRoot":"","sources":["../src/context-external-validation.ts"],"names":[],"mappings":"AAAA,cAAc,wCAAwC,CAAA"}
@@ -23,6 +23,8 @@ history but do not become a current product or release claim.
23
23
  | Use the portable shared-skill or product-discovery guidance | [Persona Shared Skills Core](persona-shared-skills-core.md) |
24
24
  | Maintain a local personalization profile | [Personalization Profile V1](personalization-profile-v1.md) |
25
25
  | Follow the Context Personalization program | [Context Personalization Program Status](context-program-status.md) |
26
+ | Contribute to Context Personalization safely | [Context contributor map](context-contributor-map.json) |
27
+ | Prepare or audit Context external validation | [Context External Validation Protocol](context-external-validation.md) |
26
28
  | Define safe project-shareable team conventions | [Team Profile V2](context-team-profile-v2.md) |
27
29
  | Understand claims and measurement limits | [Measurement scorecard](measurement-scorecard.md) |
28
30
  | Review Finish or external authority boundaries | [Consumer Authority V1 decision](consumer-authority-v1-decision.md); the repository-only external-attested walkthrough supplies the full procedure |
@@ -16,6 +16,8 @@ Start with [Current Docs](README.md) unless you need a specific decision.
16
16
  | Portable shared-skill and product-discovery contract | `docs/current/persona-shared-skills-core.md` | Catalog ownership, interview approval, explicit handoffs, host boundary, and packaged surface. |
17
17
  | Personalization profile store | `docs/current/personalization-profile-v1.md` | Versioned local profile records, append-only lifecycle, privacy, and fail-closed storage. |
18
18
  | Context Personalization program | `docs/current/context-program-status.md` | Canonical P0 audit, isolated OpenCode delivery boundary, separation invariants, and claim status. |
19
+ | Context contributor map | `docs/current/context-contributor-map.json` | Machine-checked current source ownership, credential-free local checks, and boundaries that stay separate from Context work. |
20
+ | Context external-validation protocol | `docs/current/context-external-validation.md` | Strict preregistration and finite result-status contract; default state is no observations and `INCONCLUSIVE`. |
19
21
  | Team Profile V2 boundary | `docs/current/context-team-profile-v2.md` | Read-only project-shareable v2 Team Profile schema, v1 separation, shared-text safety, and pure resolver bridge. |
20
22
  | External environment procedure | `docs/current/external-environment-verification.md` | A bounded packaged-install check on a separate machine. |
21
23
  | External-attested Finish walkthrough | `docs/current/external-attested-finish-walkthrough.md` | Source-checkout-only enrolled/fetch/Finish/replay procedure and its limits. |
@@ -0,0 +1,89 @@
1
+ {
2
+ "schemaVersion": "persona-context-contributor-map.2",
3
+ "localChecks": [
4
+ {
5
+ "script": "test",
6
+ "command": "npm test"
7
+ },
8
+ {
9
+ "script": "typecheck",
10
+ "command": "npm run typecheck"
11
+ },
12
+ {
13
+ "script": "check:docs",
14
+ "command": "npm run check:docs"
15
+ }
16
+ ],
17
+ "operationalRoutes": [
18
+ {
19
+ "id": "private-security-report",
20
+ "marker": "## Reporting a vulnerability",
21
+ "path": "SECURITY.md"
22
+ },
23
+ {
24
+ "id": "context-local-verification",
25
+ "marker": "## Context contribution route",
26
+ "path": "CONTRIBUTING.md",
27
+ "script": "test"
28
+ },
29
+ {
30
+ "id": "owner-release-operations",
31
+ "marker": "# Release Operations",
32
+ "path": "docs/current/release/README.md"
33
+ },
34
+ {
35
+ "command": "npx ph doctor",
36
+ "id": "bootstrap-intake-diagnosis",
37
+ "marker": "if (command === \"doctor\")",
38
+ "path": "src/cli/index.ts"
39
+ }
40
+ ],
41
+ "ownership": [
42
+ {
43
+ "id": "context-core",
44
+ "paths": ["src/context-core/"]
45
+ },
46
+ {
47
+ "id": "context-profile",
48
+ "paths": ["src/context-profile/"]
49
+ },
50
+ {
51
+ "id": "context-cli",
52
+ "paths": ["src/cli/context-command.ts"]
53
+ },
54
+ {
55
+ "id": "context-delivery",
56
+ "paths": ["src/context-delivery/opencode-context-hooks.ts"]
57
+ },
58
+ {
59
+ "id": "context-external-validation",
60
+ "paths": ["src/context-external-validation/"]
61
+ },
62
+ {
63
+ "id": "workflow-integrity",
64
+ "paths": ["src/cli/workflow-command.ts", "src/cli/authority-command.ts"]
65
+ }
66
+ ],
67
+ "separateBoundaries": [
68
+ {
69
+ "id": "installed-package",
70
+ "reference": "test:package"
71
+ },
72
+ {
73
+ "id": "repository-contract",
74
+ "reference": "test:repository"
75
+ },
76
+ {
77
+ "id": "p0-implementation-release",
78
+ "reference": "#414"
79
+ },
80
+ {
81
+ "id": "generic-compatibility-release",
82
+ "reference": "#412"
83
+ },
84
+ {
85
+ "id": "host-observation",
86
+ "reference": "#410"
87
+ }
88
+ ]
89
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "observations": [],
3
+ "productVerdict": "INCONCLUSIVE",
4
+ "protocol": null,
5
+ "schemaVersion": "persona-context-external-validation-status.1",
6
+ "status": "not-started"
7
+ }
@@ -0,0 +1,91 @@
1
+ # Context External Validation Protocol
2
+
3
+ Status: current Context-specific preregistration and result-status contract.
4
+
5
+ Machine-readable current state:
6
+ [`context-external-validation-status.json`](context-external-validation-status.json).
7
+ It records no protocol, no observations, and an `INCONCLUSIVE` product verdict.
8
+ That is an absence of external evidence, not a negative result and not an
9
+ invitation to simulate participants.
10
+
11
+ ## Purpose And Separation
12
+
13
+ This protocol belongs to Context Personalization M9 and is tracked by
14
+ [#429](https://github.com/jyt6640/persona-harness/issues/429). It records what
15
+ must be fixed before a future independent observation can be interpreted.
16
+
17
+ It does not replace either of these separate boundaries:
18
+
19
+ - `context-comparison-manifest.json` is deterministic local fixture evidence
20
+ for OFF, legacy-broad, and targeted layered Context composition.
21
+ - The independent Spring maintainer procedure is a Workflow Integrity
22
+ experiment and is not Context product-value evidence.
23
+
24
+ No command, runtime hook, network call, GitHub authority action, workflow
25
+ state, or participant action is implemented by this protocol. The evaluator is
26
+ pure TypeScript and only validates supplied JSON-shaped values. It is available
27
+ from the installed package as `persona-harness/context-external-validation`;
28
+ that subpath is a parser and evaluator, not an observation runner.
29
+
30
+ ## Schemas
31
+
32
+ The protocol uses `persona-context-external-validation-protocol.1`. Before any
33
+ observation begins it requires exactly:
34
+
35
+ - a 40-character candidate commit, package version, and SHA-256 tar digest;
36
+ - one SHA-256 task digest, rather than task text, prompts, source, paths, or
37
+ participant contact information;
38
+ - a three-to-five member pseudonymous cohort (`P-01` through `P-99`) with a
39
+ finite relationship category;
40
+ - a finite per-start time limit, one declared intervention policy, and the
41
+ fixed `same-task-context-off` token reference.
42
+
43
+ The result record uses `persona-context-external-validation-status.1` with
44
+ four states:
45
+
46
+ | State | Required meaning | Allowed product verdict |
47
+ | --- | --- | --- |
48
+ | `not-started` | No protocol and no observations have been recorded. | `INCONCLUSIVE` |
49
+ | `preregistered` | An exact protocol exists, but no observation has started. | `INCONCLUSIVE` |
50
+ | `observing` | A strict subset of the cohort has terminal records. | `INCONCLUSIVE` |
51
+ | `completed` | Every cohort member has exactly one terminal record. | Calculated `PRODUCT_GO` or `PRODUCT_NO_GO` |
52
+
53
+ Unknown fields, unbounded text, raw participant data, URLs, paths, credential
54
+ shapes, unsupported relationship or intervention values, candidate mismatches,
55
+ and malformed metrics are rejected. A missing protocol after `not-started`, a
56
+ partial completed denominator, or a mismatched claimed verdict is also
57
+ rejected.
58
+
59
+ ## Denominator And Verdict
60
+
61
+ Each `completed` record must contain exactly one entry for every preregistered
62
+ cohort pseudonym. An `accepted-start` carries bounded outcome metrics; a
63
+ declined or pre-start withdrawal carries only fixed `not-observed` null
64
+ metrics. This keeps every accepted start in the denominator and prevents a
65
+ selective completed result.
66
+
67
+ `PRODUCT_GO` is calculated only when all of the following are true:
68
+
69
+ 1. At least three recorded starts are independent.
70
+ 2. At least two starts reduce corrections or preserve the declared policy.
71
+ 3. Every started record completed the task, resolved its conflict accurately,
72
+ had no task regression, contradiction increase, or overreach increase, and
73
+ stayed inside the preregistered time budget.
74
+ 4. Every started record has token overhead at or below `1300` permille (1.3x)
75
+ and no maintainer intervention.
76
+
77
+ `tokenOverheadPermille` is a normalized comparison value against the fixed
78
+ `same-task-context-off` reference: `1000` means the reference amount. The
79
+ status file retains neither raw token counts nor prompts; it only accepts the
80
+ bounded normalized metric.
81
+
82
+ A valid completed cohort that misses any criterion is `PRODUCT_NO_GO`. Before
83
+ completion, or with no external evidence, the only possible verdict is
84
+ `INCONCLUSIVE`. The record never stores raw prompts, source, paths,
85
+ credentials, participant names, or free-form feedback.
86
+
87
+ ## What This Does Not Claim
88
+
89
+ The initial status does not show that an external host received Context, that a
90
+ model followed it, that users benefited, or that token use improved. It only
91
+ makes the future evidence bar reproducible and fail-closed.
@@ -3,6 +3,11 @@
3
3
  Status: current canonical program record.
4
4
 
5
5
  Last reconciled: 2026-08-30
6
+ P0 integration release: `a82b85ddef7e9fd9518348bff16deb38f53b4676`
7
+ P0 integration package: [`persona-harness@0.8.37`](https://www.npmjs.com/package/persona-harness/v/0.8.37)
8
+ P0 integration lineage: [#442](https://github.com/jyt6640/persona-harness/issues/442) delivered through [#443](https://github.com/jyt6640/persona-harness/pull/443)
9
+ Current program-status publication: [`persona-harness@0.8.38`](https://www.npmjs.com/package/persona-harness/v/0.8.38)
10
+ Program-status publication lineage: [#444](https://github.com/jyt6640/persona-harness/issues/444) reconciled through [#445](https://github.com/jyt6640/persona-harness/pull/445) and published by [#446](https://github.com/jyt6640/persona-harness/issues/446)
6
11
  P0 implementation release baseline: `9b80a45070be10659150095cf701a6f375bc6600`
7
12
  P0 implementation package: [`persona-harness@0.8.33`](https://www.npmjs.com/package/persona-harness/v/0.8.33)
8
13
  P0 implementation lineage: [#414](https://github.com/jyt6640/persona-harness/issues/414) delivered through [#437](https://github.com/jyt6640/persona-harness/pull/437)
@@ -12,9 +17,12 @@ Current comparison lineage: [#411](https://github.com/jyt6640/persona-harness/is
12
17
  Current Team Profile v2 release: `90a913168edac40eb29290e7ff47885bb94b30fd`
13
18
  Current Team Profile v2 package: [`persona-harness@0.8.35`](https://www.npmjs.com/package/persona-harness/v/0.8.35)
14
19
  Current Team Profile v2 lineage: [#421](https://github.com/jyt6640/persona-harness/issues/421) delivered through [#440](https://github.com/jyt6640/persona-harness/pull/440)
20
+ Current compatibility release: `9e8dcc3e72fab52dcb71c12c1a45cd3846929be8`
21
+ Current compatibility package: [`persona-harness@0.8.36`](https://www.npmjs.com/package/persona-harness/v/0.8.36)
22
+ Current compatibility lineage: [#412](https://github.com/jyt6640/persona-harness/issues/412) delivered through [#441](https://github.com/jyt6640/persona-harness/pull/441)
15
23
  Historical pre-integration audit source: `f677a635040ad55d8b7d25abab280c5703a153ea`
16
24
  Program issue: [#389](https://github.com/jyt6640/persona-harness/issues/389)
17
- Remaining bounded work: [#410](https://github.com/jyt6640/persona-harness/issues/410) and [#412](https://github.com/jyt6640/persona-harness/issues/412)
25
+ Remaining bounded work: hosted residual [#410](https://github.com/jyt6640/persona-harness/issues/410) and the not-started independent-value protocol from [#429](https://github.com/jyt6640/persona-harness/issues/429). The deterministic local P0 boundaries integrated by #443 are closed.
18
26
 
19
27
  ## Purpose
20
28
 
@@ -125,12 +133,14 @@ evidence rather than a description of current protected main.
125
133
  | M4 | delivered via #413 | Pure Core resolves the seven precedence layers and produces a deterministic `persona-context-envelope.v1`. | Keep Core host-neutral. |
126
134
  | M5 | implementation delivered; hosted residual | Core has no OpenCode or Java runtime import; the isolated OpenCode adapter is locally covered. | #410 may observe the real transform only after its own named Delivery Control predicate. |
127
135
  | M6 | implementation delivered; hosted residual | Context resolution, rendering, and delivery are separated from legacy workflow/authority behavior. | Preserve the isolated adapter boundary during #410. |
128
- | M7 | in progress | Historical version checks remain a maintenance concern. | #412 owns the generic Context compatibility manifest and runner. |
136
+ | M7 | delivered and released via #412/#441 | The generic Context compatibility manifest and runner are version-neutral. | Preserve the manifest-driven runner. |
129
137
  | M8 | delivered via #413 | `npm test` now selects focused source evidence and installed packages receive a separate smoke. | Keep full protected verification separate. |
130
- | M9 | implementation delivered; hosted residual | Context CLI and doctor report bounded local state without claiming host delivery. | #410 remains the sole real-host observation route after #414. |
131
- | M10 | delivered and released via #411/#439 | #411 provides a versioned three-arm protocol, strict ten-fixture manifest, and deterministic evaluator for Context OFF, legacy broad compatibility, and targeted layered envelopes. | Keep model, host, and operational measurements unavailable until a separately authorized observation; every local product verdict remains `INCONCLUSIVE`. |
132
- | M11 | in progress | Historical version-specific checks still need a version-neutral Context compatibility boundary. | #412 owns the manifest/runner work. |
133
- | M12 | verified-existing | CI critical-path optimization is already measured and active. | Preserve it and add only bounded Context checks to the correct lane. |
138
+ | M9 | deterministic protocol delivered via #429/#443; external evidence absent | Local Context inspection and deterministic fixtures do not establish independent usefulness. #429 provides the strict preregistration and result-status contract, whose committed state records no observation and `INCONCLUSIVE`. | Preserve the empty denominator until an independently authorized observation exists. |
139
+ | M10 | delivered via #411/#439 and #436/#443 | #411 provides a versioned three-arm protocol, strict ten-fixture manifest, and deterministic evaluator for Context OFF, legacy broad compatibility, and targeted layered envelopes. #436 adds an explicit clean-current-checkout source without changing the fixed corpus. | Keep model, host, and operational measurements unavailable until a separately authorized observation; every local product verdict remains `INCONCLUSIVE`. |
140
+ | M11 | delivered and released via #412/#441 | The installed-package compatibility boundary uses a generic manifest and runner. | Keep version-specific acceptance scripts out of new Context changes. |
141
+ | M12 | verified-existing; #431/#443 delivered | CI critical-path optimization is already measured and active. #431 classifies an unavailable repository observer as `clean-package-observer-gh-required` rather than a source-test failure. | Preserve the critical path; treat the named observer prerequisite as `ENVIRONMENT_BLOCKED` and add only bounded Context checks to the correct lane. |
142
+ | M13 | delivered via #412/#441 and #430/#435/#443 | Stable `v0.8.36` provides the generic manifest/runner; the contributor map and its security/release/bootstrap-intake routes give a readable credential-free contributor route. | Preserve generic package/source-fallback checks and keep the route separate from hosted or release work. |
143
+ | M14 | delivered via #433/#443 | The README entrypoint makes Context activation, authority, host, evidence, and product-focus limits explicit, with usefulness still `INCONCLUSIVE`. | Preserve the public boundary without promoting local evidence to host delivery or product value. |
134
144
 
135
145
  ## Invariants
136
146
 
@@ -148,6 +158,22 @@ evidence rather than a description of current protected main.
148
158
  - No external value or adoption claim is made without independent users and
149
159
  repositories. Current product-value verdict: **INCONCLUSIVE**.
150
160
 
161
+ ## Current Verdict
162
+
163
+ - **Technical P0 verdict: `TECHNICAL_GO`.** The deterministic Core, envelope,
164
+ Team Profile, Context CLI, default-off compatibility boundary, OpenCode
165
+ adapter composition, generic manifest runner, contributor route, package
166
+ surface, protected checks, and post-merge checks were integrated by #443 and
167
+ released as `persona-harness@0.8.37` from
168
+ `a82b85ddef7e9fd9518348bff16deb38f53b4676`.
169
+ - **Product verdict: `INCONCLUSIVE`.** The release and local deterministic
170
+ evidence do not show a real OpenCode session receiving Context or an
171
+ independent user receiving value. The #429 status intentionally has no
172
+ observations.
173
+ - **Next allowed step:** only #410's own named Delivery Control start predicate
174
+ can authorize one bounded real OpenCode observation. It is not an automatic
175
+ release follow-up, and it cannot be replaced with a synthetic or retry run.
176
+
151
177
  ## Current Delivery Order
152
178
 
153
179
  1. **Merged P0 implementation:** #390 through #403 merged and closed through
@@ -163,9 +189,19 @@ evidence rather than a description of current protected main.
163
189
  4. **Team Profile v2 release:** #421 is delivered as stable `v0.8.35` through
164
190
  #440 on `90a913168edac40eb29290e7ff47885bb94b30fd`. It preserves the
165
191
  explicit Context boundary and does not begin host observation.
166
- 5. **Remaining independent work:** #410 owns the sole real OpenCode-host
167
- observation route and #412 owns the generic installed-package compatibility
168
- boundary.
192
+ 5. **Compatibility release:** #412 is delivered as stable `v0.8.36` through
193
+ #441 on `9e8dcc3e72fab52dcb71c12c1a45cd3846929be8`. It provides the
194
+ generic installed-package compatibility manifest and runner.
195
+ 6. **P0 integration release:** #442 delivered the deterministic local P0
196
+ boundaries from #429, #430, #431, #433, #434, #435, and #436 through #443
197
+ as stable `v0.8.37` on
198
+ `a82b85ddef7e9fd9518348bff16deb38f53b4676`. The release does not create
199
+ host-delivery or product-value evidence.
200
+ 7. **Remaining independent evidence:** #410 owns the sole real OpenCode-host
201
+ observation route and still requires its own named Delivery Control start
202
+ predicate. #429 owns the preregistered external-validation schema; its
203
+ current empty status remains `INCONCLUSIVE` until a future independent
204
+ observation meets the fixed protocol.
169
205
 
170
206
  Only one public command, schema, resolver, adapter, CI, script, or documentation
171
207
  boundary is changed per child issue. A child issue closes only when its stated
@@ -195,9 +231,10 @@ not assert direct closure causality.
195
231
  | #401 | closed via #413 | Bare `ph context init` remains a no-write preview. Explicit `ph context init --enable` uses no-follow exclusive creation to write only a minimal `.persona/harness.jsonc` Context configuration in a fresh safe project. Existing regular config files, unsafe paths, and malformed arguments return finite errors without rewriting any configuration. It does not alter legacy feature flags, activate a host, or create completion state. Focused init/status/routing tests and the isolated tarball smoke cover the public surface. |
196
232
  | #402 | closed via #413 | `ph context doctor` now reuses the safe status readers instead of emitting fixed placeholder state. It reports bounded config/enablement/mode/budget/Team Profile diagnostics and explicitly distinguishes available local Core/CLI inspection from unavailable host delivery. It does not load personal rule content, write state, activate a host, or use network/shell/process/completion behavior. Focused doctor/status/routing tests and the isolated tarball smoke cover the public surface. |
197
233
  | #403 | closed via #413 | The isolated OpenCode adapter captures only safe observed targets, uses the local Context preview/envelope boundary, suppresses duplicate digests until session compaction/deletion, and mutates only the next matching user message. `context.enabled` is its sole feature switch; it does not inherit `runtimeInjection`. Adapter, actual plugin composition, status/doctor wording, type compatibility, and fail-closed target cases have focused RED-to-GREEN coverage. A real `experimental.chat.messages.transform` host observation remains separate. |
198
- | #411 | delivered through #439 | Stable `v0.8.34` binds the deterministic three-arm comparison source at `19c397e4fed5b1cce7d024fbcc51350e9676105f`. `persona-context-comparison-manifest.1` fixes ten P0 fixtures and compares `off`, `legacy-broad`, and `targeted-layered` through `persona-context-comparison-result.1`. The repository runner requires an explicit candidate commit and package version, rejects a local identity mismatch before evaluation, and produces 30 deterministic records. It emits only rule ids/layers and digests; model/host/operational fields remain `null` and every local product verdict is `INCONCLUSIVE`. |
234
+ | #411 | delivered through #439 and #443 | Stable `v0.8.34` binds the deterministic three-arm comparison source at `19c397e4fed5b1cce7d024fbcc51350e9676105f`. `persona-context-comparison-manifest.1` fixes ten P0 fixtures and compares `off`, `legacy-broad`, and `targeted-layered` through `persona-context-comparison-result.1`. The historical runner accepts explicit candidate commit and package-version metadata; #436, released through #443, adds a distinct explicit `--current-checkout` source that binds a clean root checkout before evaluation. Both forms produce 30 deterministic records and emit only rule ids/layers and digests; model/host/operational fields remain `null` and every local product verdict is `INCONCLUSIVE`. |
199
235
  | #414 | delivered through #437 | Stable `v0.8.33` binds the P0 implementation package/source release lineage. It is immutable historical release evidence and does not authorize #410, a host session, or any Context product claim by itself. |
200
236
  | #421 | delivered through #440 | Stable `v0.8.35` binds the Team Profile v2 source at `90a913168edac40eb29290e7ff47885bb94b30fd`. The separate JSONC loader and explicit pure-resolver layer reject unknown fields, unsafe shared text, duplicate ids, active topic conflicts, malformed JSONC, and symlinked files without reading personal state or activating a host. | Release and provenance evidence do not begin CLI delivery, adapter delivery, runtime activation, or external effectiveness observation. |
237
+ | #442 | delivered through #443 | Stable `v0.8.37` binds the integrated deterministic P0 boundary to `a82b85ddef7e9fd9518348bff16deb38f53b4676`. It includes the external-validation schema/status, contributor route, default-off claim boundary, current-checkout comparison route, and observer prerequisite classification. | The release does not substitute for #410's real host observation or turn the empty #429 protocol into product evidence. |
201
238
 
202
239
  The heavy `test:installed-package-contract` and full protected repository suite
203
240
  remain unchanged. The generic package smoke is version-neutral and does not
@@ -245,8 +282,9 @@ was not modified.
245
282
  | P0 implementation | #413 merged at `a562331f9db321845b05da1e16edc4b83bf78ece`; #390 through #403 are observed closed after that merge. | No integration PR remains. |
246
283
  | P0 implementation release lineage | #414 delivered stable `v0.8.33` through #437. Its immutable tag, GitHub Release, npm `latest`, canonical tar, and provenance bind to `9b80a45070be10659150095cf701a6f375bc6600`. | Historical P0 implementation release evidence does not prove live host delivery. |
247
284
  | Deterministic comparison release lineage | #411 delivered stable `v0.8.34` through #439. Its immutable tag, GitHub Release, npm `latest`, canonical tar, and provenance bind to `19c397e4fed5b1cce7d024fbcc51350e9676105f`. | It records only deterministic technical results; host/model/operational values remain unavailable and product verdicts remain `INCONCLUSIVE`. |
248
- | Hosted Context delivery | The current published comparison package contains the merged #403 adapter boundary, but no package/release record substitutes for the #410 start predicate. | #410 still needs its own named Delivery Control start predicate and one bounded real OpenCode observation. |
249
- | Other follow-ups | #421 is delivered as stable `v0.8.35` through #440; #412 owns the generic Context compatibility runner. | #412 may not manufacture host or user-value evidence. |
285
+ | Current P0 integration release | #442 delivered stable `v0.8.37` through #443. Its immutable tag, GitHub Release, npm `latest`, canonical tar, and provenance bind to `a82b85ddef7e9fd9518348bff16deb38f53b4676`. | It closes the deterministic local P0 boundaries, not #410's real host observation or external product-value evidence. |
286
+ | Hosted Context delivery | The current program-status publication `0.8.38` retains the merged #403 adapter boundary, but no package/release record substitutes for the #410 start predicate. | #410 still needs its own named Delivery Control start predicate and one bounded real OpenCode observation. |
287
+ | Other follow-ups | #421 is delivered as stable `v0.8.35` through #440; #412 is delivered as stable `v0.8.36` through #441; the #429 protocol is released through #443 with zero observations. | None of these facts manufacture host or user-value evidence. |
250
288
 
251
289
  Product-value verdict remains **INCONCLUSIVE**. Local composition, package,
252
290
  release, and CI evidence do not establish host-session delivery or user benefit.
@@ -254,15 +292,20 @@ release, and CI evidence do not establish host-session delivery or user benefit.
254
292
  ## #411 Comparison Protocol
255
293
 
256
294
  The Context comparison runner is repository-side tooling, not an installed
257
- user command. It requires an explicit full candidate commit and package version
258
- so it can reject a checkout mismatch before it evaluates the fixed corpus:
295
+ user command. Its default command explicitly selects the clean current
296
+ checkout as the candidate source:
259
297
 
260
298
  ```bash
261
- npm run benchmark:context -- \
262
- --candidate-commit <full-current-commit> \
263
- --package-version <exact-package-version>
299
+ npm run benchmark:context
264
300
  ```
265
301
 
302
+ The runner reads only the local Git root, full `HEAD`, clean working-tree state,
303
+ and root `package.json` version for that mode. For reproducible supplied
304
+ metadata, invoke the runner directly with both `--candidate-commit` and
305
+ `--package-version`; mixing the two source forms, partial metadata, a dirty
306
+ checkout, or a package root outside the Git root fails before manifest
307
+ evaluation.
308
+
266
309
  It produces one `persona-context-comparison-result.1` record for each of ten
267
310
  fixtures and three arms. It emits only rule identifiers, layers, and digests;
268
311
  host/model/operational measurements remain `null` and product verdicts remain
@@ -281,9 +324,11 @@ expand the released Context delivery scope or change its default-off boundary.
281
324
 
282
325
  ## Next Action
283
326
 
284
- Do not reopen the completed #390–#403 integration or #414 release paths.
285
- Delivery Control must record #410's own named hosted start predicate before one
286
- real OpenCode `experimental.chat.messages.transform` observation can begin.
287
- #412 remains an independent follow-up boundary. Do not infer host delivery or
288
- product value from local composition tests, catalog registration, release
289
- provenance, or historical evidence.
327
+ No deterministic local Context P0 candidate remains open after #443. Do not
328
+ reopen the completed #390–#403 integration, #414 release, or #442 integration
329
+ paths. Delivery Control must record #410's own named hosted start predicate
330
+ before one real OpenCode `experimental.chat.messages.transform` observation can
331
+ begin. The #429 protocol remains `INCONCLUSIVE` with zero observations; do not
332
+ infer host delivery or product value from local composition tests, catalog
333
+ registration, release provenance, an empty external-validation status, or
334
+ historical evidence.
@@ -59,6 +59,9 @@ Total indexed files: 342
59
59
  | `docs/current/clean-opencode-ph-bearshell-smoke.md` | current compatibility doc | - | Compatibility/current-era doc retained in place; migrate by summary and pointer before moving. |
60
60
  | `docs/current/consumer-authority-v1-decision.md` | current active pointer/status | - | Issue #108 V1 decision: the only enabled authority behavior is explicit `workflow finish implement --assurance cooperative` within the same Finish invocation after fixed local verification and one-time in-memory consumption; it is non-persistent, status/fetch/later closure remain blocked, and default/external boundaries remain blocked. |
61
61
  | `docs/current/context-comparison-manifest.json` | current test fixture manifest | - | Exact ten-fixture source-only corpus for the Context OFF, legacy broad compatibility, and targeted layered comparison protocol. |
62
+ | `docs/current/context-contributor-map.json` | current test fixture manifest | - | Machine-readable current source-path and npm-script bindings for the Context contributor ownership map and local verification route. |
63
+ | `docs/current/context-external-validation-status.json` | current active pointer/status | - | Machine-readable initial state for the Context external-validation protocol; it records no observations and an `INCONCLUSIVE` product verdict. |
64
+ | `docs/current/context-external-validation.md` | current active pointer/status | - | Context-specific preregistration, denominator, privacy, and finite outcome contract for future independent observation; it does not record one. |
62
65
  | `docs/current/context-program-status.md` | current active pointer/status | - | Canonical P0 audit and isolated OpenCode delivery status for the default-off Context Personalization track and its separation from Workflow Integrity. |
63
66
  | `docs/current/context-team-profile-v2.md` | current active pointer/status | - | Read-only project-shareable Team Profile v2 schema, safety boundary, v1 separation, and pure resolver bridge. |
64
67
  | `docs/current/desktop-test-artifacts-index.md` | current compatibility doc | - | Compatibility/current-era doc retained in place; migrate by summary and pointer before moving. |
@@ -25,7 +25,7 @@
25
25
  "package": {
26
26
  "channel": "unpublished",
27
27
  "scope": "source-candidate",
28
- "version": "0.8.36"
28
+ "version": "0.8.38"
29
29
  },
30
30
  "currentSourceCandidate": {
31
31
  "registryInstall": "requires-authorized-release-before-registry-install",
@@ -0,0 +1,38 @@
1
+ # v0.8.37 Release Notes
2
+
3
+ ## Context P0 Boundaries
4
+
5
+ This release consolidates the deterministic Context Personalization boundaries
6
+ that stay separate from Workflow Integrity. It adds a preregistered
7
+ external-validation protocol with an explicit empty result state, contributor
8
+ ownership and operational-route maps, a public README claim boundary, and a
9
+ benchmark command bound to the clean checked-out source identity.
10
+
11
+ The comparison protocol continues to distinguish deterministic technical
12
+ results from product usefulness. Without a preregistered external observation,
13
+ the product verdict remains `INCONCLUSIVE`.
14
+
15
+ ## Repository Contract Clarity
16
+
17
+ The full repository contract now classifies an unavailable selected observer
18
+ path as `clean-package-observer-gh-required`. This is an
19
+ `ENVIRONMENT_BLOCKED` prerequisite, not a source-test failure. Empty or missing
20
+ observer input stops before package preparation; nonempty malformed paths remain
21
+ argument errors.
22
+
23
+ ## Safety And Scope Boundaries
24
+
25
+ - Context remains explicit opt-in and default-off.
26
+ - Context-only paths do not infer workflow, shell/process execution, network,
27
+ GitHub, evidence, authority, credential, or host-observation actions.
28
+ - This release does not claim a live OpenCode delivery result, external user
29
+ result, token saving, or product efficacy.
30
+ - Historical releases remain immutable and cannot supply current package or
31
+ host-observation evidence.
32
+
33
+ ## Verification
34
+
35
+ The delivery path verifies default unit and integration contracts, Context
36
+ comparison source binding, type safety, documentation and release-policy
37
+ checks, a fresh isolated tarball installation, protected CI, canonical package
38
+ identity, and registry provenance.
@@ -0,0 +1,38 @@
1
+ # v0.8.38 Release Notes
2
+
3
+ ## Context P0 Program Record
4
+
5
+ This release publishes the reconciled Context Personalization P0 program
6
+ record in the installed package. It distinguishes the completed deterministic
7
+ technical boundary from the still-unmeasured live-host and external-value
8
+ boundaries.
9
+
10
+ The deterministic P0 verdict is `TECHNICAL_GO`. The product verdict remains
11
+ `INCONCLUSIVE`: no release, package, CI result, or local fixture is evidence
12
+ of a real host-session delivery or user benefit.
13
+
14
+ ## What Changed
15
+
16
+ - Package the current Context P0 status record and its explicit delivery
17
+ lineage.
18
+ - Preserve the immutable `0.8.37` P0 integration release as the deterministic
19
+ implementation baseline.
20
+ - State that issue #410 remains a separately gated real-host observation; this
21
+ release does not start it.
22
+
23
+ ## Safety And Scope Boundaries
24
+
25
+ - Context remains explicit opt-in and default-off.
26
+ - Context-only paths do not infer workflow, shell/process execution, network,
27
+ GitHub, evidence, authority, credential, or host-observation actions.
28
+ - This release does not claim a live OpenCode delivery result, external user
29
+ result, token saving, or product efficacy.
30
+ - Historical releases remain immutable and cannot supply current package or
31
+ host-observation evidence.
32
+
33
+ ## Verification
34
+
35
+ The release path verifies source and integration contracts, type safety,
36
+ documentation and release-policy checks, a fresh isolated tarball
37
+ installation, protected CI, canonical package identity, and registry
38
+ provenance.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "persona-harness",
3
- "version": "0.8.36",
3
+ "version": "0.8.38",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "packageManager": "npm@10.8.2",
@@ -14,6 +14,7 @@
14
14
  },
15
15
  "exports": {
16
16
  ".": "./dist/index.js",
17
+ "./context-external-validation": "./dist/context-external-validation.js",
17
18
  "./effective-profile": "./dist/effective-profile.js",
18
19
  "./portable-skill": "./dist/portable-skill.js"
19
20
  },
@@ -62,6 +63,9 @@
62
63
  "docs/current/v0.3.0-alpha-publish-readiness.md",
63
64
  "docs/current/persona-harness-detailed-usage.md",
64
65
  "docs/current/context-program-status.md",
66
+ "docs/current/context-contributor-map.json",
67
+ "docs/current/context-external-validation.md",
68
+ "docs/current/context-external-validation-status.json",
65
69
  "docs/current/context-team-profile-v2.md",
66
70
  "docs/current/README.md",
67
71
  "docs/current/personalization-profile-v1.md",
@@ -340,10 +344,10 @@
340
344
  "observe:test-contract": "node scripts/observe-test-contract.mjs",
341
345
  "measure:entry-steering": "npm run build && node experiments/entry-intent-corpus/measure.mjs",
342
346
  "report:rules": "npm run build && node scripts/report-rule-diagnostics.mjs",
343
- "benchmark:context": "npm run build && node scripts/eval/run-context-comparison.mjs --manifest docs/current/context-comparison-manifest.json",
347
+ "benchmark:context": "npm run build && node scripts/eval/run-context-comparison.mjs --manifest docs/current/context-comparison-manifest.json --current-checkout",
344
348
  "test": "node scripts/run-default-test.mjs",
345
349
  "test:fast": "npm run test:unit && npm run test:integration",
346
- "test:unit": "vitest run --testTimeout=15000 tests/npm-test-contract.test.ts tests/context-compatibility-manifest.test.ts tests/context-config.test.ts tests/context-comparison.test.ts tests/context-comparison-runner.test.ts tests/context-core-import-boundary.test.ts tests/context-envelope-builder.test.ts tests/effective-context-v2.test.ts tests/effective-profile-resolution.test.ts tests/phase0-harness-config.test.ts tests/opencode-skill-adapter.test.ts",
350
+ "test:unit": "vitest run --testTimeout=15000 tests/npm-test-contract.test.ts tests/context-compatibility-manifest.test.ts tests/context-config.test.ts tests/context-comparison.test.ts tests/context-comparison-runner.test.ts tests/context-contributor-route.test.ts tests/context-core-import-boundary.test.ts tests/context-envelope-builder.test.ts tests/context-external-validation.test.ts tests/context-program-status.test.ts tests/context-readme-boundary.test.ts tests/effective-context-v2.test.ts tests/effective-profile-resolution.test.ts tests/phase0-harness-config.test.ts tests/opencode-skill-adapter.test.ts",
347
351
  "test:integration": "vitest run --testTimeout=15000 tests/context-command-routing.test.ts tests/context-doctor.test.ts tests/context-init.test.ts tests/context-preview.test.ts tests/context-explain.test.ts tests/context-status.test.ts tests/opencode-context-delivery.test.ts tests/personalization-profile-store.test.ts tests/team-profile-store.test.ts tests/team-profile-v2-store.test.ts tests/phase0-runtime-context-delivery.test.ts tests/personalization-profile-package-contract.test.ts",
348
352
  "test:smoke": "npm run build && node dist/cli/index.js --help",
349
353
  "test:full": "npm run test:repository",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@persona-harness/shared-skills",
3
- "version": "0.8.36",
3
+ "version": "0.8.38",
4
4
  "type": "module",
5
5
  "private": true,
6
6
  "description": "Persona-owned portable skill procedures and optional overlays",