persona-harness 0.8.21 → 0.8.22

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.
@@ -9,13 +9,15 @@ version/package chronology, use
9
9
  [`docs/releases/README.md`](../../releases/README.md) and
10
10
  [`docs/releases/package-index.md`](../../releases/package-index.md).
11
11
 
12
- ## Current 0.8.21 Package Authority
12
+ ## Current 0.8.22 Package Authority
13
13
 
14
- The current unpublished package authority is 0.8.21. Its root package,
15
- lockfile, private shared-skills package, and v0821 acceptance record must agree
16
- exactly. The published 0.8.20 release is immutable historical evidence only
14
+ The current unpublished package authority is 0.8.22. Its root package,
15
+ lockfile, private shared-skills package, and v0822 acceptance record must agree
16
+ exactly. The published 0.8.21 release is immutable historical evidence only
17
17
  and must not be retagged, rerun, or published.
18
- The package-visible read-only `ph authority verify` surface never fetches,
18
+ The package-visible read-only `ph authority verify` surface accepts canonical
19
+ `sha256:<64hex>` or an exact raw SHA-256 hex digest, normalizing either form
20
+ before the same no-follow archive boundary. It never fetches,
19
21
  persists, consumes, finishes, or replays authority. Its `.2` result exposes a
20
22
  finite `sourceReason` only alongside `source-mismatch`; unavailable Sigstore
21
23
  trust remains a fixed blocked result rather than a trust claim.
@@ -92,7 +92,7 @@ caller that already holds one original archive:
92
92
  ```text
93
93
  ph authority verify [owner/repository] --archive <original-archive> \
94
94
  --artifact-id <id> --run-id <run-id> --source-head <commit> \
95
- --artifact-digest sha256:<digest> --json
95
+ --artifact-digest <sha256:<digest>|64hex> --json
96
96
  ```
97
97
 
98
98
  The command requires all four tuple fields, the current enrolled source and
@@ -102,6 +102,10 @@ and checks its digest before invoking the existing verifier. It never reads a
102
102
  GitHub credential, fetches an artifact, writes the authority store, consumes
103
103
  authority, runs Finish, or performs replay.
104
104
 
105
+ The digest is canonicalized to lowercase `sha256:<64hex>`. Callers may supply
106
+ that canonical form or an exact raw 64-character SHA-256 hex digest; every
107
+ other form remains blocked before archive verification.
108
+
105
109
  Its public result is `consumer-authority-verify.2` with fixed fields for
106
110
  eligibility, consumption state, bounded reason, schema, source-fallback state,
107
111
  and terminal state. Only `source-mismatch` includes a finite nonreflective
@@ -1,12 +1,11 @@
1
1
  # v0.8.21 Release Notes
2
2
 
3
- ## Current package authority
3
+ ## Historical package authority
4
4
 
5
- `0.8.21` is the current unpublished package authority. The root package,
5
+ `0.8.21` was published as an immutable stable release. Its root package,
6
6
  lockfile, private shared-skills package, and
7
- `consumer-authority-v0821-acceptance.json` bind the same version. Published
8
- `0.8.20` is immutable historical evidence and cannot authorize this candidate
9
- or a replacement publish.
7
+ `consumer-authority-v0821-acceptance.json` remain historical release evidence;
8
+ they cannot authorize a later candidate or a second publish.
10
9
 
11
10
  ## Portable repair source identity
12
11
 
@@ -22,9 +21,8 @@ The exclusion is intentionally narrow. A reviewed
22
21
  all other tracked or untracked source stay in the signed identity and continue
23
22
  to drift or fail closed as before.
24
23
 
25
- ## Release boundary
24
+ ## Historical boundary
26
25
 
27
- Fresh Source and Package gates must bind the exact `0.8.21` candidate and its
28
- canonical tar before protected integration, stable Release, and one npm
29
- `latest` publication. A released successor package is the lawful fixture-pin
30
- trigger for #338; fixture and V4 observations remain separately governed.
26
+ The release completed through protected integration, a stable GitHub Release,
27
+ and one npm `latest` publication. Fixture and V4 observations remain separate
28
+ evidence paths and do not alter this immutable release history.
@@ -0,0 +1,28 @@
1
+ # v0.8.22 Release Notes
2
+
3
+ ## Current package authority
4
+
5
+ `0.8.22` is the current unpublished package authority. The root package,
6
+ lockfile, private shared-skills package, and
7
+ `consumer-authority-v0822-acceptance.json` bind the same version. Published
8
+ `0.8.21` is immutable historical evidence and cannot authorize this candidate
9
+ or a replacement publish.
10
+
11
+ ## Authority verify digest normalization
12
+
13
+ The installed read-only `ph authority verify` command accepts either its
14
+ canonical `sha256:<64hex>` archive digest or an exact raw 64-character
15
+ SHA-256 hex value. Raw input is normalized before archive comparison, so both
16
+ forms bind the same tuple and retain the existing no-follow, enrollment,
17
+ source, crypto, and non-consuming boundaries.
18
+
19
+ Partial tuples, invalid sizes or characters, unsupported algorithms, duplicate
20
+ flags, symlink archives, and tuple mismatches still block before verifier,
21
+ store, fetch, Finish, or replay.
22
+
23
+ ## Release boundary
24
+
25
+ Fresh Source and Package gates must bind the exact `0.8.22` candidate and its
26
+ canonical tar before protected integration, stable Release, and one npm
27
+ `latest` publication. A released successor package is the lawful fixture-pin
28
+ trigger for #307; fixture and V4 observations remain separately governed.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "persona-harness",
3
- "version": "0.8.21",
3
+ "version": "0.8.22",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "packageManager": "npm@10.8.2",
@@ -248,6 +248,8 @@
248
248
  "scripts/consumer-authority-v0820-acceptance-schema.mjs",
249
249
  "scripts/consumer-authority-v0821-acceptance-schema.d.mts",
250
250
  "scripts/consumer-authority-v0821-acceptance-schema.mjs",
251
+ "scripts/consumer-authority-v0822-acceptance-schema.d.mts",
252
+ "scripts/consumer-authority-v0822-acceptance-schema.mjs",
251
253
  "scripts/consumer-authority-v081-acceptance-schema.d.mts",
252
254
  "scripts/consumer-authority-v081-acceptance-schema.mjs",
253
255
  "scripts/consumer-authority-rc1-acceptance-schema.mjs",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@persona-harness/shared-skills",
3
- "version": "0.8.21",
3
+ "version": "0.8.22",
4
4
  "type": "module",
5
5
  "private": true,
6
6
  "description": "Persona-owned portable skill procedures and optional overlays",
@@ -0,0 +1,40 @@
1
+ export const V0822_ACCEPTANCE_SCHEMA_VERSION: "consumer-authority-v0822-acceptance.1"
2
+
3
+ export class V0822AcceptanceManifestError extends Error {
4
+ readonly code: "v0822-acceptance-schema"
5
+ }
6
+
7
+ export type V0822AcceptanceManifest = Readonly<Record<string, unknown>> & Readonly<{
8
+ readonly authority: Readonly<{
9
+ readonly readOnlyVerify: Readonly<{
10
+ readonly archiveInput: Readonly<{
11
+ readonly ancestorDirectoryChurn: string
12
+ readonly arbitrarySymlinkAncestorOrLeaf: string
13
+ readonly darwinSystemTemporaryAlias: string
14
+ readonly directParentIntegrity: string
15
+ readonly nonDarwin: string
16
+ }>
17
+ readonly artifactDigestInput: string
18
+ readonly command: string
19
+ readonly noCredentialFetchStoreConsumeFinishReplay: boolean
20
+ readonly schemaVersion: string
21
+ }>
22
+ }>
23
+ readonly package: Readonly<{
24
+ readonly channel: string
25
+ readonly scope: string
26
+ readonly version: string
27
+ }>
28
+ readonly initialization: Readonly<{
29
+ readonly packageTemplateIdentity: string
30
+ readonly repairStaging: string
31
+ }>
32
+ readonly projectFinishSourceIdentity: Readonly<{
33
+ readonly adoptedInstructionPolicy: string
34
+ readonly repairInferenceObservations: string
35
+ }>
36
+ }>
37
+
38
+ export function canonicalV0822AcceptanceManifest(): V0822AcceptanceManifest
39
+ export function readV0822AcceptanceManifest(packageRoot: string): V0822AcceptanceManifest
40
+ export function parseV0822AcceptanceManifest(value: unknown, packageVersion: string): V0822AcceptanceManifest
@@ -0,0 +1,83 @@
1
+ import { readFileSync } from "node:fs"
2
+ import { join } from "node:path"
3
+ import { isDeepStrictEqual } from "node:util"
4
+
5
+ import { canonicalV0821AcceptanceManifest } from "./consumer-authority-v0821-acceptance-schema.mjs"
6
+ import { parseCanonicalPackagePublisherPlan } from "./canonical-package-publisher.mjs"
7
+ import { parseExternalArtifactTransportPlan } from "./consumer-authority-external-artifact-transport-plan.mjs"
8
+ import { parseExternalAttestationCommandPlan } from "./consumer-authority-external-attestation-command-plan.mjs"
9
+ import { parseObserverGhToolContract } from "./consumer-authority-observer-gh-tool.mjs"
10
+
11
+ export const V0822_ACCEPTANCE_SCHEMA_VERSION = "consumer-authority-v0822-acceptance.1"
12
+
13
+ const V0822_PACKAGE_VERSION = "0.8.22"
14
+ const ACCEPTANCE_PATH = join("docs", "current", "release", "consumer-authority-v0822-acceptance.json")
15
+ const EXPECTED_MANIFEST = buildExpectedManifest()
16
+
17
+ export class V0822AcceptanceManifestError extends Error {
18
+ constructor(code) {
19
+ super(code)
20
+ this.code = code
21
+ }
22
+ }
23
+
24
+ export function canonicalV0822AcceptanceManifest() {
25
+ return structuredClone(EXPECTED_MANIFEST)
26
+ }
27
+
28
+ export function readV0822AcceptanceManifest(packageRoot) {
29
+ let packageVersion
30
+ let value
31
+ try {
32
+ packageVersion = JSON.parse(readFileSync(join(packageRoot, "package.json"), "utf8")).version
33
+ value = JSON.parse(readFileSync(join(packageRoot, ACCEPTANCE_PATH), "utf8"))
34
+ } catch {
35
+ fail()
36
+ }
37
+ return parseV0822AcceptanceManifest(value, packageVersion)
38
+ }
39
+
40
+ export function parseV0822AcceptanceManifest(value, packageVersion) {
41
+ if (packageVersion !== V0822_PACKAGE_VERSION || !isDeepStrictEqual(value, EXPECTED_MANIFEST)) fail()
42
+ parseCanonicalPackagePublisherPlan(value.canonicalPackagePublisherPlan)
43
+ parseExternalAttestationCommandPlan(value.externalAttestationCommandPlan)
44
+ parseExternalArtifactTransportPlan(value.externalArtifactTransportPlan)
45
+ parseObserverGhToolContract(value.observerGhTool)
46
+ return value
47
+ }
48
+
49
+ function buildExpectedManifest() {
50
+ const manifest = canonicalV0821AcceptanceManifest()
51
+ manifest.schemaVersion = V0822_ACCEPTANCE_SCHEMA_VERSION
52
+ manifest.package.channel = "unpublished"
53
+ manifest.package.scope = "source-candidate"
54
+ manifest.package.version = V0822_PACKAGE_VERSION
55
+ delete manifest.v0820HistoricalRelease
56
+ manifest.v0821HistoricalRelease = {
57
+ outcome: "published-0.8.21-release-is-immutable-and-not-reusable-for-this-unpublished-v0822-source-candidate-or-any-later-package",
58
+ reusableForV0822: false,
59
+ version: "0.8.21",
60
+ }
61
+ manifest.initialization = {
62
+ packageTemplateIdentity: "canonical-package-template-digest-remains-separate-from-effective-bootstrap-overlay-file-digests",
63
+ repairStaging: "manifest-less-recognized-portable-static-baseline-records-the-caller-realpath-before-staging-ownership-verification",
64
+ }
65
+ manifest.projectFinishSourceIdentity = {
66
+ adoptedInstructionPolicy: "remains-source-bound",
67
+ repairInferenceObservations: "excludes-only-.persona/instructions/inferred.json-and-.persona/instructions/conflicts.json",
68
+ }
69
+ manifest.authority.readOnlyVerify.archiveInput = {
70
+ ...manifest.authority.readOnlyVerify.archiveInput,
71
+ ancestorDirectoryChurn: "same-no-follow-directory-location-and-mode-required-while-unrelated-entry-metadata-may-change",
72
+ directParentIntegrity: "full-no-follow-identity-remains-required-before-read",
73
+ }
74
+ manifest.authority.readOnlyVerify.artifactDigestInput = "canonical-sha256-prefix-or-exact-64-hex-normalized-before-archive-verification"
75
+ manifest.authority.fixturePlan.registryInstall = "requires-authorized-release-before-registry-install-persona-harness@0.8.22"
76
+ manifest.authority.hostedFixture.revision = "v0822-source-candidate-head-before-authorized-release"
77
+ manifest.hostedResidual.id = "v0822-current-package-acceptance-and-authorized-current-artifact-observation"
78
+ return manifest
79
+ }
80
+
81
+ function fail() {
82
+ throw new V0822AcceptanceManifestError("v0822-acceptance-schema")
83
+ }
@@ -2,7 +2,7 @@ import { realpathSync } from "node:fs"
2
2
  import { dirname } from "node:path"
3
3
  import { fileURLToPath, pathToFileURL } from "node:url"
4
4
 
5
- import { readV0821AcceptanceManifest } from "./consumer-authority-v0821-acceptance-schema.mjs"
5
+ import { readV0822AcceptanceManifest } from "./consumer-authority-v0822-acceptance-schema.mjs"
6
6
  import { runExternalArtifactTransportPreflight } from "./consumer-authority-external-artifact-transport-plan.mjs"
7
7
 
8
8
  const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)))
@@ -14,7 +14,7 @@ async function main() {
14
14
  process.exitCode = 1
15
15
  return
16
16
  }
17
- readV0821AcceptanceManifest(packageRoot)
17
+ readV0822AcceptanceManifest(packageRoot)
18
18
  const result = await runExternalArtifactTransportPreflight()
19
19
  process.stdout.write(`${JSON.stringify(result)}\n`)
20
20
  process.exitCode = result.state === "ready" ? 0 : 1
@@ -2,7 +2,7 @@ import { realpathSync } from "node:fs"
2
2
  import { dirname } from "node:path"
3
3
  import { fileURLToPath, pathToFileURL } from "node:url"
4
4
 
5
- import { readV0821AcceptanceManifest } from "./consumer-authority-v0821-acceptance-schema.mjs"
5
+ import { readV0822AcceptanceManifest } from "./consumer-authority-v0822-acceptance-schema.mjs"
6
6
  import { runExternalAttestationGrammarPreflight } from "./consumer-authority-external-attestation-command-plan.mjs"
7
7
 
8
8
  const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)))
@@ -15,7 +15,7 @@ function main() {
15
15
  process.exitCode = 1
16
16
  return
17
17
  }
18
- const manifest = readV0821AcceptanceManifest(packageRoot)
18
+ const manifest = readV0822AcceptanceManifest(packageRoot)
19
19
  const result = runExternalAttestationGrammarPreflight(
20
20
  manifest.externalAttestationCommandPlan,
21
21
  grammarOnlyTopology(manifest),