owlrunkit 0.17.2 → 0.18.1

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 (33) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/README.md +117 -14
  3. package/docs/architecture/OWLCODA_RUNKIT_017_AGENT_NATIVE_PRODUCT_DEFINITION.md +2 -3
  4. package/docs/architecture/OWLCODA_RUNKIT_018_PROJECT_DRIVER_PRODUCT_DEFINITION.md +165 -0
  5. package/docs/architecture/OWLCODA_RUNKIT_USAGE_MODE_SELECTION_PRODUCT_DECISION_20260811.md +142 -0
  6. package/integrations/codex/skills/owlcoda-runkit/SKILL.md +127 -23
  7. package/integrations/codex/skills/owlcoda-runkit/assets/templates/config.json +3 -3
  8. package/package.json +2 -2
  9. package/packages/attest/distribution-manifest-v1.json +10 -0
  10. package/packages/attest/src/quick.mjs +10 -0
  11. package/registry-release-policy-v1.json +5 -5
  12. package/sbom.spdx.json +5 -5
  13. package/scripts/runkit-contract/assurance-router.mjs +28 -20
  14. package/scripts/runkit-contract/core-contract.mjs +7 -1
  15. package/scripts/runkit-contract/inspect-presentation.mjs +38 -5
  16. package/scripts/runkit-contract/install-codex-skill.mjs +60 -1
  17. package/scripts/runkit-contract/onboarding-doctor.mjs +19 -1
  18. package/scripts/runkit-contract/profile-onboarding.mjs +597 -22
  19. package/scripts/runkit-contract/project-cli-resolver.mjs +6 -0
  20. package/scripts/runkit-contract/quick-attest.mjs +1 -0
  21. package/scripts/runkit-contract/quick-metrics.mjs +43 -5
  22. package/scripts/runkit-contract/quick-verify.mjs +15 -4
  23. package/scripts/runkit-contract/runkit-cli.mjs +747 -20
  24. package/scripts/runkit-contract/schemas/profile-reconcile-plan-v1.schema.json +105 -0
  25. package/scripts/runkit-contract/schemas/profile-reconcile-receipt-v1.schema.json +60 -0
  26. package/scripts/runkit-contract/schemas/team-project-event-v1.schema.json +16 -1
  27. package/scripts/runkit-contract/schemas/team-project-status-v1.schema.json +34 -1
  28. package/scripts/runkit-contract/schemas/team-project-successor-receipt-v1.schema.json +204 -0
  29. package/scripts/runkit-contract/schemas/usage-mode-recommendation-v1.schema.json +136 -0
  30. package/scripts/runkit-contract/team-project-successor.mjs +1176 -0
  31. package/scripts/runkit-contract/team-project.mjs +1082 -43
  32. package/scripts/runkit-contract/templates/assurance-request.json +6 -0
  33. package/scripts/runkit-contract/usage-mode.mjs +229 -0
@@ -1,28 +1,35 @@
1
1
  ---
2
2
  name: owlcoda-runkit
3
- description: Run receipt-backed, project-owned work with OwlCoda RunKit. Use when Codex needs to coordinate a large multi-Agent project, show per-Agent progress, manage dependencies or decisions, hand work to another Agent, recover a blank-session next action, initialize or inspect `.owlcoda/runkit/`, plan bounded work with engine pins and leases, capture exact verification evidence, close an execution, produce a ready-for-commit receipt, or perform a read-only foreign-project shadow without widening Git or release authority.
3
+ description: Run receipt-backed, project-owned work with OwlCoda RunKit. Use when Codex needs to coordinate a large multi-Agent project, show per-Agent progress, manage dependencies or decisions, record intentionally deferred verification without repeating covered tests, hand work to another Agent, recover a blank-session next action, initialize or inspect `.owlcoda/runkit/`, plan bounded work with engine pins and leases, capture exact verification evidence, close an execution, produce a ready-for-commit receipt, or perform a read-only foreign-project shadow without widening Git or release authority.
4
4
  ---
5
5
 
6
6
  # OwlCoda RunKit
7
7
 
8
8
  Use the bundled deterministic Core to coordinate work through project artifacts rather than chat memory. Require Node.js 20 or later.
9
9
 
10
- Bundled release: standalone `owlrunkit@0.17.2`, bundling Contract `0.2` and
11
- Core `0.17.2` with manifest
12
- `sha256:67b883b8a763253b873fb6047c7e7e01c81123aa5250a0db5feaabd13cc4d860`.
13
- Publication and dist-tag state are mutable registry facts: verify the exact
14
- official npm registry provenance before adoption. The immutable rollback
15
- baseline for this release is `owlrunkit@0.16.1` with SHA-1
10
+ Bundled release: standalone `owlrunkit@0.18.1`, bundling Contract `0.2` and
11
+ Core `0.18.1` with manifest
12
+ `sha256:349b4157d3d089462b172de1619ccd169b5c1669b9322e2580ac6ec4f8616b07`.
13
+ The published `owlrunkit@0.18.0` package is the trusted prior for rollback;
14
+ verify exact official npm registry provenance before adoption. The immutable
15
+ rollback baseline for the prior release is `owlrunkit@0.16.1` with SHA-1
16
16
  `1bc119d24879bdd8959af16b364af55ca9d61ea9` and canonical npm tarball URL
17
17
  `https://registry.npmjs.org/owlrunkit/-/owlrunkit-0.16.1.tgz`.
18
18
  The root `owlcoda` package has a separate version lifecycle.
19
19
 
20
20
  The session is an execution interface. Project artifacts are the system of record.
21
21
 
22
- ## Agent-native project actions
22
+ ## Project Driver actions
23
23
 
24
- Translate ordinary user requests into durable project actions. Do not ask the
25
- user to operate the CLI when the request and authority are already clear.
24
+ Translate ordinary user requests into durable typed project actions. Do not ask
25
+ the user to operate the CLI when the request and authority are already clear.
26
+
27
+ The normal mainline is `init`, `assign`, `checkpoint`, `handoff`, `decision`,
28
+ `verification`, `integrate`, `status`, and `takeover`. After a project
29
+ derives completed, `successor` is the bounded lifecycle step. `init` accepts one project definition
30
+ JSON; subsequent actions use direct typed flags. Normal users do not author
31
+ request, event, receipt, or hash JSON. The legacy `--request <event.json>` form
32
+ remains available for existing automation and compatibility.
26
33
 
27
34
  - "Split this large task and run it in parallel": initialize one project
28
35
  definition before dispatch, then assign a distinct WorkItem to each Agent.
@@ -35,10 +42,23 @@ user to operate the CLI when the request and authority are already clear.
35
42
  never overwrite the old assignment.
36
43
  - "Continue/take over": build `project takeover` for the current Agent and use
37
44
  its bounded next action and evidence refs.
45
+ - "Start the next project": only after status derives `overall=completed`,
46
+ invoke `project successor` with a different V1 definition and explicit
47
+ transition ID. Preserve the content-addressed archive and journal; never
48
+ use handoff, takeover, install, or publication as successor authority.
38
49
  - "Capture this as data": append a data candidate only. Never call it a dataset
39
50
  member without a separate admission decision.
40
- - "Verify/finish": select No RunKit, Quick, or Formal from risk; bind a Formal
41
- WorkItem to its actual execution and lease when applicable.
51
+ - "Do not run that check yet": append one deferred verification with stable
52
+ check IDs, reason, owner, WorkItem, and due integration gate. This records an
53
+ unrun check; it does not execute or schedule one.
54
+ - "That deferred check is done": close it as `verified` with evidence. If the
55
+ check is no longer required, first resolve an explicit project decision and
56
+ close it as `no_longer_required` with that decision ID. Never report the
57
+ second disposition as a passing test.
58
+ - "Verify/finish": select continuity and assurance independently from the
59
+ underlying risk; bind a Formal WorkItem to its actual execution and lease when
60
+ applicable. Multi-Agent coordination, long duration, or interruption recovery
61
+ alone does not select Formal.
42
62
 
43
63
  For a multi-Agent project, checkpoint meaningful state changes promptly. A
44
64
  checkpoint is not a heartbeat and must not contain a guessed percentage.
@@ -47,12 +67,72 @@ state from the closeout and lease rather than trusting the Agent's claim.
47
67
 
48
68
  ```bash
49
69
  owlrunkit project init --workspace "$PROJECT_ROOT" --definition "$PROJECT_JSON"
50
- owlrunkit project assign --workspace "$PROJECT_ROOT" --request "$EVENT_JSON"
51
- owlrunkit project checkpoint --workspace "$PROJECT_ROOT" --request "$EVENT_JSON"
70
+ owlrunkit project assign --workspace "$PROJECT_ROOT" --assignment-id "$ASSIGNMENT_ID" \
71
+ --at "$OCCURRED_AT" --work-item "$WORK_ITEM_ID" --agent "$AGENT_ID"
72
+ owlrunkit project checkpoint --workspace "$PROJECT_ROOT" --checkpoint-id "$CHECKPOINT_ID" \
73
+ --at "$OCCURRED_AT" --assignment-id "$ASSIGNMENT_ID" --work-item "$WORK_ITEM_ID" \
74
+ --state active --summary "$SUMMARY" --next "$NEXT_ACTION"
75
+ owlrunkit project handoff --workspace "$PROJECT_ROOT" --handoff-id "$HANDOFF_ID" \
76
+ --at "$OCCURRED_AT" --assignment-id "$ASSIGNMENT_ID" --work-item "$WORK_ITEM_ID" \
77
+ --from-agent "$AGENT_ID" --to-agent "$SUCCESSOR_AGENT_ID" \
78
+ --summary "$SUMMARY" --next "$NEXT_ACTION" --evidence "$EVIDENCE_REF"
79
+ owlrunkit project decision --workspace "$PROJECT_ROOT" --resolve \
80
+ --decision-id "$DECISION_ID" --at "$OCCURRED_AT" --resolution "$RESOLUTION" \
81
+ --rationale "$RATIONALE" --evidence "$EVIDENCE_REF"
82
+ owlrunkit project verification --workspace "$PROJECT_ROOT" --defer \
83
+ --verification-id "$VERIFICATION_ID" --at "$OCCURRED_AT" \
84
+ --work-item "$WORK_ITEM_ID" --owner-agent "$AGENT_ID" \
85
+ --check "$CHECK_ID" --reason "$REASON" --due-gate "$GATE_ID"
86
+ owlrunkit project verification --workspace "$PROJECT_ROOT" --close \
87
+ --verification-id "$VERIFICATION_ID" --at "$OCCURRED_AT" \
88
+ --disposition verified --summary "$SUMMARY" --evidence "$EVIDENCE_REF"
89
+ owlrunkit project integrate --workspace "$PROJECT_ROOT" --gate "$GATE_ID" \
90
+ --at "$OCCURRED_AT" --summary "$SUMMARY" --evidence "$EVIDENCE_REF"
52
91
  owlrunkit project status --workspace "$PROJECT_ROOT" --json
53
92
  owlrunkit project takeover --workspace "$PROJECT_ROOT" --agent "$AGENT_ID" --json
93
+ owlrunkit project successor --workspace "$PROJECT_ROOT" \
94
+ --transition-id "$TRANSITION_ID" --at "$OCCURRED_AT" \
95
+ --definition "$NEXT_PROJECT_JSON" --reason "$SUCCESSOR_REASON" --json
54
96
  ```
55
97
 
98
+ `project successor` accepts only a derived-completed active project and a
99
+ different fresh V1 identity. It archives the exact prior bytes, never borrows
100
+ old events, and resumes only an identical durable transition. Treat symlinks,
101
+ collisions, competing transition IDs, incomplete truth, and changed truth as
102
+ fail-closed. The archived tree is sealed against ordinary writes. Exact retry
103
+ validates its archive bytes and seal, and each later successor validates every
104
+ completed transition archive before changing active truth or writing its own
105
+ journal. Do not infer a historical archive scan from `status` or `takeover`;
106
+ those remain active-truth projections. The receipt never grants Git, release,
107
+ publication, deployment, package-adoption, or writer authority.
108
+
109
+ ## Batch verification around a small explainable closure
110
+
111
+ Use a verification micro-batch when two or three related changes share one
112
+ module or contract, one writer, one worktree, one causal hypothesis, and one
113
+ acceptance level. During implementation, run only the smallest smoke or
114
+ falsifier needed to reject a wrong direction. After the related changes settle,
115
+ freeze the candidate and run its focused suite once.
116
+
117
+ Run typecheck, lint, build, and diff checks once at candidate closeout unless a
118
+ later edit invalidates them. Keep broad suites, installed-package checks,
119
+ deployment checks, production reads, and large data hashes at the actual state
120
+ transition that needs them. Do not run them early just to make an intermediate
121
+ packet look complete.
122
+
123
+ Independent acceptance first validates candidate identity and trustworthy
124
+ coverage, then adds fresh adversarial or boundary scenarios. It does not repeat
125
+ the implementer's whole covered suite unless the receipt is missing, stale,
126
+ drifted, flaky, or insufficient for the requested acceptance level.
127
+
128
+ Do not defer an immediate containment, authorization, symlink/realpath,
129
+ rollback-safety, security, money, or data-integrity falsifier. Split a batch
130
+ when ownership, worktree, authority, hypothesis, or acceptance level differs,
131
+ or when a failure would no longer be attributable. An open deferred
132
+ verification remains visible in `status` and `takeover` and blocks its declared
133
+ integration gate; it never grants permission to run the check or any later
134
+ Git, release, deployment, or production action.
135
+
56
136
  ## Start safely
57
137
 
58
138
  1. Locate the project root and read its AGENTS.md chain.
@@ -165,6 +245,11 @@ node "$RUNKIT_PACKAGE_ROOT/scripts/runkit-contract/install-codex-skill.mjs" \
165
245
  --target "$RUNKIT_SKILL_TARGET" --archive "$RUNKIT_SKILL_ARCHIVE_ROOT"
166
246
  ```
167
247
 
248
+ `inspect` checks both managed-file integrity and the Skill/config Core version
249
+ against the package that runs the command. A `version_mismatch` result is an
250
+ explicit upgrade diagnostic; it is not evidence that the installed Skill was
251
+ loaded into the current session and grants no update authority.
252
+
168
253
  The install manifest binds every Skill, Core, contract and attest file.
169
254
  Unknown installed drift fails closed instead of being overwritten. A changed
170
255
  process-wide Skill requires a registered complete fleet. Register each coverage
@@ -253,6 +338,8 @@ owlrunkit fleet register-root --fleet-root /absolute/declared-projects
253
338
  owlrunkit fleet discover
254
339
  owlrunkit profiles detect --workspace "$PROJECT_ROOT" --dry-run
255
340
  owlrunkit profiles detect --workspace "$PROJECT_ROOT" --apply
341
+ owlrunkit profiles reconcile --workspace "$PROJECT_ROOT" --dry-run
342
+ owlrunkit mode recommend --workspace "$PROJECT_ROOT"
256
343
  owlrunkit assurance route --workspace "$PROJECT_ROOT" \
257
344
  --request "$ASSURANCE_REQUEST_JSON"
258
345
  owlrunkit status --workspace "$PROJECT_ROOT"
@@ -261,28 +348,45 @@ owlrunkit status --workspace "$PROJECT_ROOT"
261
348
  Fleet discovery is complete only within all registered coverage roots, an
262
349
  explicit one-off root list, or a caller-supplied frozen `--fleet-manifest`. It
263
350
  refuses unreachable roots and cannot protect projects outside registered
264
- coverage. `profiles detect --apply` is create-only and adopts only unambiguous
265
- high-confidence, project-local regular-file launchers; existing profiles and
266
- low-confidence candidates remain untouched. Lock-bound npm and exact
351
+ coverage. `profiles detect --apply` creates only an absent profile set and
352
+ adopts only unambiguous high-confidence, project-local regular-file launchers;
353
+ `profiles reconcile` previews or atomically updates an existing profile set
354
+ with a rollback receipt. Low-confidence candidates remain untouched. Lock-bound npm and exact
267
355
  project-installed pnpm, Yarn, and Bun launchers are supported; PATH-only
268
356
  package managers remain review-required. `assurance route`
269
357
  deterministically selects No RunKit, Quick Verification or Formal Delivery
270
358
  from explicit risk facts and fails closed to Formal when required facts are
271
359
  missing.
272
360
 
273
- ## Choose the smallest assurance lane
361
+ ## Choose continuity and assurance independently
362
+
363
+ Start with `owlrunkit mode recommend --workspace "$PROJECT_ROOT"`. The five
364
+ user-facing modes are presets over two independent dimensions:
365
+
366
+ - continuity: `none | project_driver`
367
+ - assurance: `none | quick | formal`
274
368
 
275
- Choose the lane before planning. Do not create a Formal execution merely
276
- because this skill is available.
369
+ Use `off` for analysis, documentation, and disposable exploration; `light` for
370
+ one frozen low-risk candidate plus one Quick command; `managed` for Project
371
+ Driver continuity with per-WorkItem assurance; and `formal` only at a genuine
372
+ Formal boundary. `auto` derives those choices from facts. The selected mode is
373
+ a workflow preference, never authorization.
277
374
 
278
375
  - Use ordinary project tools without RunKit for disposable prototypes, early
279
376
  research, visual exploration or clean short tasks that need no durable
280
377
  handoff, evidence consumption or formal acceptance.
281
378
  - Use Quick Verification for one low-risk command that needs a source-bound,
282
379
  reusable verification receipt but no writer lease or formal acceptance.
283
- - Use Formal Delivery for multi-writer work, long-running or interrupted work,
284
- dirty parallel workspaces, migration, integration, release, production,
285
- funds or another delivery requiring formal acceptance.
380
+ - Use Project Driver for cross-session, long-running, interrupted, or durable
381
+ handoff needs. A managed WorkItem may still use no assurance or one Quick.
382
+ - Use Formal Delivery for multi-writer work, permission or security boundaries,
383
+ funds, irreversible changes, uncertain rollback, schema/data migration, or
384
+ an explicit Formal-acceptance contract.
385
+
386
+ Production, release, deployment, ordinary source mutation, long duration, and
387
+ interruption labels do not force Formal by themselves. When the forcing fact is
388
+ contained, route again and allow de-escalation. `off`, `light`, or `managed`
389
+ cannot override a still-present mandatory Formal fact.
286
390
 
287
391
  If work crosses lanes, re-evaluate risk and authority. Moving from Quick to
288
392
  Formal requires a fresh GoalContract, exact write scope, profiles and authority;
@@ -2,9 +2,9 @@
2
2
  "schemaVersion": "OwlCodaRunKitConfigV2",
3
3
  "core": {
4
4
  "contractVersion": "0.2",
5
- "coreVersion": "0.17.2",
6
- "coreManifestSha256": "sha256:67b883b8a763253b873fb6047c7e7e01c81123aa5250a0db5feaabd13cc4d860",
7
- "coreSourceRef": "artifact:sha256:67b883b8a763253b873fb6047c7e7e01c81123aa5250a0db5feaabd13cc4d860"
5
+ "coreVersion": "0.18.1",
6
+ "coreManifestSha256": "sha256:349b4157d3d089462b172de1619ccd169b5c1669b9322e2580ac6ec4f8616b07",
7
+ "coreSourceRef": "artifact:sha256:349b4157d3d089462b172de1619ccd169b5c1669b9322e2580ac6ec4f8616b07"
8
8
  },
9
9
  "authorizationPolicy": "external_explicit_authority_required"
10
10
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "owlrunkit",
3
- "version": "0.17.2",
4
- "description": "Project-owned execution, evidence, verification, and recovery for coding agents.",
3
+ "version": "0.18.1",
4
+ "description": "Project Driver for cross-Agent project continuity and progression; execution, evidence, verification, and recovery are the underlying trust substrate.",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "author": "yeemio <owlclaw@163.com>",
7
7
  "type": "module",
@@ -36,6 +36,16 @@
36
36
  "sha256": "sha256:3972dc9744f6499f0f9b2dbf76696f2ae7ad8af9b23dde66d6af86c9dfb36986"
37
37
  },
38
38
  "supportedProducerCoreIdentities": [
39
+ {
40
+ "contractVersion": "0.2",
41
+ "coreVersion": "0.18.1",
42
+ "coreManifestSha256": "sha256:349b4157d3d089462b172de1619ccd169b5c1669b9322e2580ac6ec4f8616b07"
43
+ },
44
+ {
45
+ "contractVersion": "0.2",
46
+ "coreVersion": "0.18.0",
47
+ "coreManifestSha256": "sha256:72c481dbafe06a9c56cd940d74a3fe109a82b73a3c43d0bb54923ea6c584c04e"
48
+ },
39
49
  {
40
50
  "contractVersion": "0.2",
41
51
  "coreVersion": "0.17.2",
@@ -18,6 +18,16 @@ import { captureWorkspaceSnapshot } from "./workspace-snapshot.mjs";
18
18
  export { validQuickReceiptShape } from "./quick-receipt-contract.mjs";
19
19
 
20
20
  export const SUPPORTED_QUICK_CORE_IDENTITIES = Object.freeze([
21
+ {
22
+ contractVersion: "0.2",
23
+ coreVersion: "0.18.1",
24
+ coreManifestSha256: "sha256:349b4157d3d089462b172de1619ccd169b5c1669b9322e2580ac6ec4f8616b07",
25
+ },
26
+ {
27
+ contractVersion: "0.2",
28
+ coreVersion: "0.18.0",
29
+ coreManifestSha256: "sha256:72c481dbafe06a9c56cd940d74a3fe109a82b73a3c43d0bb54923ea6c584c04e",
30
+ },
21
31
  {
22
32
  contractVersion: "0.2",
23
33
  coreVersion: "0.17.2",
@@ -2,7 +2,7 @@
2
2
  "schemaVersion": "OwlCodaRunKitRegistryReleasePolicyV1",
3
3
  "status": "release_candidate_unpublished",
4
4
  "packageName": "owlrunkit",
5
- "candidateVersion": "0.17.2",
5
+ "candidateVersion": "0.18.1",
6
6
  "registry": "https://registry.npmjs.org",
7
7
  "registryRequiredBeforeAdoption": true,
8
8
  "exactVersionRequired": true,
@@ -23,10 +23,10 @@
23
23
  ],
24
24
  "currentPublishedRelease": {
25
25
  "packageName": "owlrunkit",
26
- "version": "0.17.1",
27
- "shasum": "819a824d6df7f89fe8c0a68756e20c446fd67936",
28
- "integrity": "sha512-Oget/g3MHQaWp1gs7VP/mw3DSlSD4a+vDy3a+3z/8AQ715rLvmkc0ikuz/3T/rcIa0Pw8IecBgqrJu+Lpaf/4w==",
29
- "tarballUrl": "https://registry.npmjs.org/owlrunkit/-/owlrunkit-0.17.1.tgz"
26
+ "version": "0.18.0",
27
+ "shasum": "ab2d9c9ed81f9dcccd4c1affa519cfca1cc32032",
28
+ "integrity": "sha512-asi4CKofzjzQ9gGxnv6/NDCM6rZcMMqpwd4uRStfUUwDetFLYHEPDMBv1JGvYotdUwwoODxwdJ3KMGXQSYorgA==",
29
+ "tarballUrl": "https://registry.npmjs.org/owlrunkit/-/owlrunkit-0.18.0.tgz"
30
30
  },
31
31
  "registryRelease": null,
32
32
  "registryEvidenceMustBeExternal": true,
package/sbom.spdx.json CHANGED
@@ -2,8 +2,8 @@
2
2
  "spdxVersion": "SPDX-2.3",
3
3
  "dataLicense": "CC0-1.0",
4
4
  "SPDXID": "SPDXRef-DOCUMENT",
5
- "name": "owlrunkit-0.17.2",
6
- "documentNamespace": "https://owlcoda.com/spdx/owlrunkit/0.17.2",
5
+ "name": "owlrunkit-0.18.1",
6
+ "documentNamespace": "https://owlcoda.com/spdx/owlrunkit/0.18.1",
7
7
  "creationInfo": {
8
8
  "created": "2026-07-29T00:00:00Z",
9
9
  "creators": [
@@ -14,8 +14,8 @@
14
14
  {
15
15
  "name": "owlrunkit",
16
16
  "SPDXID": "SPDXRef-Package-OwlRunKit",
17
- "versionInfo": "0.17.2",
18
- "downloadLocation": "https://registry.npmjs.org/owlrunkit/-/owlrunkit-0.17.2.tgz",
17
+ "versionInfo": "0.18.1",
18
+ "downloadLocation": "https://registry.npmjs.org/owlrunkit/-/owlrunkit-0.18.1.tgz",
19
19
  "filesAnalyzed": false,
20
20
  "licenseConcluded": "GPL-3.0-or-later",
21
21
  "licenseDeclared": "GPL-3.0-or-later",
@@ -24,7 +24,7 @@
24
24
  {
25
25
  "referenceCategory": "PACKAGE-MANAGER",
26
26
  "referenceType": "purl",
27
- "referenceLocator": "pkg:npm/owlrunkit@0.17.2"
27
+ "referenceLocator": "pkg:npm/owlrunkit@0.18.1"
28
28
  }
29
29
  ]
30
30
  }
@@ -6,6 +6,12 @@ const BOOLEAN_FACTS = [
6
6
  "longRunning",
7
7
  "interruptionRecovery",
8
8
  "dirtyParallelWorkspace",
9
+ "irreversibleChange",
10
+ "rollbackUncertain",
11
+ "permissionSensitive",
12
+ "securitySensitive",
13
+ "fundsAtRisk",
14
+ "schemaOrDataMigration",
9
15
  ];
10
16
 
11
17
  const RISK_CATEGORIES = new Set([
@@ -20,13 +26,11 @@ const RISK_CATEGORIES = new Set([
20
26
  "release",
21
27
  ]);
22
28
 
23
- const FULL_RISK_CATEGORIES = new Set([
24
- "deployment",
29
+ const MATERIAL_RISK_CATEGORIES = new Set([
25
30
  "destructive",
26
31
  "foreign_write",
27
32
  "funds",
28
- "production",
29
- "release",
33
+ "migration",
30
34
  ]);
31
35
 
32
36
  function incompleteReasons(input) {
@@ -76,26 +80,21 @@ export function routeRunKitAssuranceV1(input) {
76
80
  const categories = [...new Set(input.riskCategories)].sort();
77
81
  const formalReasons = [
78
82
  ...(input.needsFormalAcceptance ? ["formal_acceptance_required"] : []),
79
- ...(input.mayMutateProject ? ["project_mutation"] : []),
80
- ...(input.externalSideEffects ? ["external_side_effects"] : []),
81
- ...(input.longRunning ? ["long_running_execution"] : []),
82
- ...(input.interruptionRecovery ? ["interruption_recovery_required"] : []),
83
- ...(input.dirtyParallelWorkspace ? ["dirty_parallel_workspace"] : []),
84
- ...(input.writerCount > 0 ? ["writer_scope_required"] : []),
85
- ...(input.needsDurableEvidence && input.exactCommandCount === 0
86
- ? ["exact_command_missing"]
87
- : []),
88
- ...(input.needsDurableEvidence && input.exactCommandCount > 1
89
- ? ["multiple_commands"]
90
- : []),
91
- ...categories.map(category => `risk_${category}`),
83
+ ...(input.writerCount > 1 ? ["multiple_writers"] : []),
84
+ ...(input.permissionSensitive === true ? ["permission_sensitive"] : []),
85
+ ...(input.securitySensitive === true ? ["security_sensitive"] : []),
86
+ ...(input.fundsAtRisk === true ? ["funds_at_risk"] : []),
87
+ ...(input.irreversibleChange === true ? ["irreversible_change"] : []),
88
+ ...(input.rollbackUncertain === true ? ["rollback_uncertain"] : []),
89
+ ...(input.schemaOrDataMigration === true ? ["schema_or_data_migration"] : []),
90
+ ...categories
91
+ .filter(category => MATERIAL_RISK_CATEGORIES.has(category))
92
+ .map(category => `risk_${category}`),
92
93
  ];
93
94
  if (formalReasons.length > 0) {
94
- const full = input.externalSideEffects
95
- || categories.some(category => FULL_RISK_CATEGORIES.has(category));
96
95
  return result({
97
96
  lane: "formal",
98
- riskMode: full ? "full" : "standard",
97
+ riskMode: "full",
99
98
  reasonCodes: [...new Set(formalReasons)].sort(),
100
99
  nextCommand: "owlrunkit formal start",
101
100
  });
@@ -110,6 +109,15 @@ export function routeRunKitAssuranceV1(input) {
110
109
  });
111
110
  }
112
111
 
112
+ if (input.exactCommandCount !== 1) {
113
+ return result({
114
+ lane: "none",
115
+ riskMode: "lightweight",
116
+ reasonCodes: ["quick_exact_command_required"],
117
+ nextCommand: null,
118
+ });
119
+ }
120
+
113
121
  return result({
114
122
  lane: "quick",
115
123
  riskMode: "lightweight",
@@ -14,7 +14,7 @@ import { fileURLToPath } from "node:url";
14
14
  import { parseProjectControlState } from "./project-control-parser.mjs";
15
15
 
16
16
  export const CONTRACT_VERSION = "0.2";
17
- export const CORE_VERSION = "0.17.2";
17
+ export const CORE_VERSION = "0.18.1";
18
18
  export const RUNTIME_ROOT = ".owlcoda/runkit";
19
19
 
20
20
  const CORE_FILES = [
@@ -66,7 +66,9 @@ const CORE_FILES = [
66
66
  "source-candidate.mjs",
67
67
  "source-fingerprint.mjs",
68
68
  "sync-release-identity.mjs",
69
+ "team-project-successor.mjs",
69
70
  "team-project.mjs",
71
+ "usage-mode.mjs",
70
72
  "verification-envelope.mjs",
71
73
  "verification-envelope-check.mjs",
72
74
  "verification-receipt-gate.mjs",
@@ -100,6 +102,8 @@ const CORE_FILES = [
100
102
  "schemas/owner-deployment-decision-v1.schema.json",
101
103
  "schemas/profile-apply-receipt-v1.schema.json",
102
104
  "schemas/profile-detection-v2.schema.json",
105
+ "schemas/profile-reconcile-plan-v1.schema.json",
106
+ "schemas/profile-reconcile-receipt-v1.schema.json",
103
107
  "schemas/project-config.schema.json",
104
108
  "schemas/project-config-v2.schema.json",
105
109
  "schemas/profiles.schema.json",
@@ -122,7 +126,9 @@ const CORE_FILES = [
122
126
  "schemas/verification-context-v1.schema.json",
123
127
  "schemas/team-project-definition-v1.schema.json",
124
128
  "schemas/team-project-event-v1.schema.json",
129
+ "schemas/team-project-successor-receipt-v1.schema.json",
125
130
  "schemas/team-project-status-v1.schema.json",
131
+ "schemas/usage-mode-recommendation-v1.schema.json",
126
132
  "schemas/verification-envelope-v1.schema.json",
127
133
  "schemas/verification-finalize-attempt-v1.schema.json",
128
134
  "schemas/verification-preflight-v1.schema.json",
@@ -40,7 +40,7 @@ function closeoutDecisionCounts(inspected) {
40
40
 
41
41
  export function buildInspectSummary(
42
42
  inspected,
43
- { maintenanceNextAction = null } = {},
43
+ { maintenanceNextAction = null, projectDriver = null } = {},
44
44
  ) {
45
45
  const humanStatus = deriveHumanStatusFromInspectV1(inspected);
46
46
  const focus = selectedFocus(inspected);
@@ -80,6 +80,21 @@ export function buildInspectSummary(
80
80
  ...(inspected.controlIssues ?? []),
81
81
  ...(selectedResource?.blockers ?? []),
82
82
  ].filter((reason, index, all) => all.indexOf(reason) === index);
83
+ const projectGapCode = projectDriver === null
84
+ ? null
85
+ : projectDriver.dominantGap.id === null
86
+ ? projectDriver.dominantGap.kind
87
+ : `${projectDriver.dominantGap.kind}:${projectDriver.dominantGap.id}`;
88
+ const projectDriverSummary = projectDriver === null
89
+ ? null
90
+ : {
91
+ projectId: projectDriver.projectId,
92
+ overall: projectDriver.overall,
93
+ headline: projectDriver.headline,
94
+ dominantGap: structuredClone(projectDriver.dominantGap),
95
+ nextAction: projectDriver.nextAction,
96
+ nextActorId: projectDriver.nextActorId,
97
+ };
83
98
  return {
84
99
  schemaVersion: "OwlCodaRunKitInspectSummaryV1",
85
100
  currentExecution: {
@@ -139,13 +154,22 @@ export function buildInspectSummary(
139
154
  resources: [...(selectedResource?.resources ?? [])],
140
155
  },
141
156
  dominantGap: {
142
- code: humanStatus.nextAllowedAction,
143
- reasons: [...reasons],
157
+ code: projectGapCode ?? humanStatus.nextAllowedAction,
158
+ reasons: projectDriver === null
159
+ ? [...reasons]
160
+ : [projectDriver.dominantGap.reason].filter(Boolean),
144
161
  },
162
+ ...(projectDriverSummary === null ? {} : { projectDriver: projectDriverSummary }),
145
163
  lifecycleNextAction: inspected.recovery.nextAllowedAction,
146
164
  maintenanceNextAction,
147
165
  optionalReviewAction: independentHistory ? "inspect_closed_history" : null,
148
166
  nextAllowedAction: humanStatus.nextAllowedAction,
167
+ ...(projectDriver === null
168
+ ? {}
169
+ : {
170
+ recommendedNextAction:
171
+ projectDriver.nextAction ?? humanStatus.nextAllowedAction,
172
+ }),
149
173
  authorizationGranted: false,
150
174
  gitAuthorization: false,
151
175
  releaseAuthorization: false,
@@ -192,8 +216,17 @@ function summaryLines(summary, humanStatus) {
192
216
  ? `$${summary.resourcePreflight.estimate.cost.valueUsd}`
193
217
  : "unknown"}`,
194
218
  `Receipt reuse: ${summary.resourcePreflight.receiptReuse.appliedCount}/${summary.resourcePreflight.receiptReuse.reusableCount}`,
195
- `Dominant gap: ${summary.dominantGap.code}`,
196
- `Next allowed action: ${summary.nextAllowedAction}`,
219
+ ...(summary.projectDriver
220
+ ? [
221
+ `Project dominant gap: ${summary.dominantGap.code}`,
222
+ `Recommended next action: ${value(summary.recommendedNextAction)}`,
223
+ `Execution state: ${summary.currentExecution.state}`,
224
+ `Execution next allowed action: ${summary.nextAllowedAction}`,
225
+ ]
226
+ : [
227
+ `Dominant gap: ${summary.dominantGap.code}`,
228
+ `Next allowed action: ${summary.nextAllowedAction}`,
229
+ ]),
197
230
  ...(summary.maintenanceNextAction
198
231
  ? [`Maintenance: ${summary.maintenanceNextAction}`]
199
232
  : []),
@@ -16,6 +16,7 @@ import path from "node:path";
16
16
  import { pathToFileURL } from "node:url";
17
17
 
18
18
  import {
19
+ currentCoreIdentity,
19
20
  initializeProjectRunKit,
20
21
  isDirectExecution,
21
22
  validateProjectConfigV2,
@@ -193,6 +194,64 @@ export async function inspectInstalledSkill({ targetRoot } = {}) {
193
194
  };
194
195
  }
195
196
 
197
+ export async function inspectInstalledSkillCompatibility({ targetRoot } = {}) {
198
+ const integrity = await inspectInstalledSkill({ targetRoot });
199
+ if (!integrity.valid) {
200
+ return {
201
+ ...integrity,
202
+ integrityValid: false,
203
+ authorizationGranted: false,
204
+ };
205
+ }
206
+
207
+ const expectedCore = currentCoreIdentity();
208
+ let installedSkillVersion = null;
209
+ let installedConfigCore = null;
210
+ const issues = [];
211
+ try {
212
+ const skillText = await readFile(path.join(targetRoot, "SKILL.md"), "utf8");
213
+ installedSkillVersion = skillText.match(/standalone `owlrunkit@(\d+\.\d+\.\d+)`/u)?.[1] ?? null;
214
+ installedConfigCore = JSON.parse(await readFile(
215
+ path.join(targetRoot, "assets/templates/config.json"),
216
+ "utf8",
217
+ )).core ?? null;
218
+ } catch {
219
+ issues.push("installed_skill_version_declaration_invalid");
220
+ }
221
+
222
+ const installedConfigCoreVersion = installedConfigCore?.coreVersion ?? null;
223
+ if (installedSkillVersion === null || installedConfigCoreVersion === null) {
224
+ issues.push("installed_skill_core_version_declaration_missing");
225
+ } else if (
226
+ installedSkillVersion !== expectedCore.coreVersion
227
+ || installedConfigCoreVersion !== expectedCore.coreVersion
228
+ ) {
229
+ issues.push(
230
+ `installed_skill_core_version_mismatch:expected_${expectedCore.coreVersion}`
231
+ + `:skill_${installedSkillVersion}:config_${installedConfigCoreVersion}`,
232
+ );
233
+ } else if (!sameCoreIdentity(installedConfigCore, expectedCore)) {
234
+ issues.push(
235
+ `installed_skill_core_identity_mismatch:expected_${expectedCore.coreManifestSha256}`
236
+ + `:config_${installedConfigCore?.coreManifestSha256 ?? "missing"}`,
237
+ );
238
+ }
239
+
240
+ return {
241
+ ...integrity,
242
+ status: issues.length === 0 ? "valid" : "version_mismatch",
243
+ valid: issues.length === 0,
244
+ integrityValid: true,
245
+ expectedCoreVersion: expectedCore.coreVersion,
246
+ expectedCore,
247
+ installedSkillVersion,
248
+ installedConfigCoreVersion,
249
+ installedConfigCore,
250
+ issues,
251
+ authorizationGranted: false,
252
+ };
253
+ }
254
+
196
255
  export async function inspectFleetForSkillChange({
197
256
  workspaceRoots = null,
198
257
  fleetManifestPath = null,
@@ -731,7 +790,7 @@ export async function runCli(argv = process.argv.slice(2)) {
731
790
  return { exitCode: 0, ...output };
732
791
  }
733
792
  if (command === "inspect") {
734
- const output = await inspectInstalledSkill({ targetRoot: options.target });
793
+ const output = await inspectInstalledSkillCompatibility({ targetRoot: options.target });
735
794
  return { exitCode: output.valid ? 0 : 2, ...output };
736
795
  }
737
796
  if (command === "restore") {
@@ -583,6 +583,24 @@ function profilesCheck(root) {
583
583
  }
584
584
  }
585
585
 
586
+ async function doctorProfilesCheck(root) {
587
+ const launcherCheck = profilesCheck(root);
588
+ if (launcherCheck.status === "missing") return launcherCheck;
589
+ const { validateProfiles } = await import("./profile-onboarding.mjs");
590
+ const validation = validateProfiles({ workspaceRoot: root });
591
+ const issues = [...new Set([
592
+ ...(launcherCheck.launcherIssues ?? []),
593
+ ...validation.issues,
594
+ ])].sort();
595
+ return {
596
+ ...launcherCheck,
597
+ status: issues.length === 0 ? "ok" : "invalid",
598
+ validationStatus: validation.status,
599
+ validationIssues: validation.issues,
600
+ ...(issues.length > 0 ? { issues } : {}),
601
+ };
602
+ }
603
+
586
604
  export function readProfileLauncherReadiness({ workspaceRoot } = {}) {
587
605
  const profiles = profilesCheck(resolveBoundedWorkspaceRoot(workspaceRoot));
588
606
  const launcherWarnings = profiles.launcherWarnings ?? [];
@@ -646,7 +664,7 @@ export async function runDoctor({
646
664
  });
647
665
  const nodeOk = Number(process.versions.node.split(".")[0]) >= 20;
648
666
  const config = configCheck(root);
649
- const profiles = profilesCheck(root);
667
+ const profiles = await doctorProfilesCheck(root);
650
668
  const adoption = adoptionCheck(root, installed);
651
669
  const runtimeIsolation = runtimeIsolationCheck(root);
652
670
  const checks = {