@hasna/contracts 0.1.0 → 0.1.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.
- package/README.md +98 -3
- package/dist/cli/index.js +2 -2
- package/dist/index.js +1 -1
- package/dist/schemas.d.ts +1 -1
- package/dist/schemas.js +1 -1
- package/dist/validators.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -143,6 +143,7 @@ Common resource-kind mappings:
|
|
|
143
143
|
| `open-todos` | `task`, `project`, `verification`, `proof_bundle` |
|
|
144
144
|
| `open-loops` | `loop`, `workflow`, `run`, `artifact` |
|
|
145
145
|
| `open-actions` | `action`, `tool`, `event`; decisions are emitted as `DecisionEnvelope` contracts, not resource kinds |
|
|
146
|
+
| `open-automations` | `action`, `tool`, `event`; deterministic recipe decisions are emitted as `DecisionEnvelope` contracts |
|
|
146
147
|
| `open-sessions` | `session`, `run`, `machine`, `artifact` |
|
|
147
148
|
| `open-context` | `context_pack`, `file`, `url`, `knowledge` |
|
|
148
149
|
| `open-knowledge` / `open-mementos` | `knowledge`, `memento`, `context_pack` |
|
|
@@ -158,10 +159,17 @@ helpers. Owning packages still own storage and behavior.
|
|
|
158
159
|
|
|
159
160
|
- `open-todos` owns tasks, task plans, locks, comments, and task evidence.
|
|
160
161
|
- `open-loops` owns loop and workflow execution.
|
|
162
|
+
- `open-events` owns event envelopes, channels, delivery, replay, and
|
|
163
|
+
notification semantics.
|
|
161
164
|
- `open-actions` owns executable action manifests.
|
|
165
|
+
- `open-automations` owns deterministic product/app automations and
|
|
166
|
+
connector/action recipes. It does not own agent workflow invocation,
|
|
167
|
+
admission queues, task/PR/review worker routing, or canonical workflow run
|
|
168
|
+
artifacts.
|
|
162
169
|
- `open-sessions` owns transcript and trajectory ingestion.
|
|
163
170
|
- `open-context` owns context-pack construction and retrieval.
|
|
164
|
-
- `open-knowledge` owns durable knowledge records and promotion workflows
|
|
171
|
+
- `open-knowledge` owns durable knowledge records and promotion workflows under
|
|
172
|
+
`.hasna/knowledge`.
|
|
165
173
|
- `open-files` owns artifact storage, file indexing, and dereference logic.
|
|
166
174
|
- `open-mementos` owns memory lifecycle and recall.
|
|
167
175
|
- `open-reports` owns rendered reports and proof presentation.
|
|
@@ -179,10 +187,16 @@ native domain objects immediately.
|
|
|
179
187
|
records, versions, signed URLs, source manifests, and evidence assets.
|
|
180
188
|
- `open-todos`: expose task refs as `ResourceRef`; verification evidence as
|
|
181
189
|
`ProofBundle`; task execution receipts as `WorkRun`; review gates as
|
|
182
|
-
`ValidationPlan
|
|
190
|
+
`ValidationPlan`; and workflow/run manifest pointers as compact task fields,
|
|
191
|
+
not embedded handoff artifacts.
|
|
183
192
|
- `open-loops`: emit loop/workflow runs as `WorkRun`, audit traces as
|
|
184
193
|
`AgentTrajectory`, logs/artifacts as `EvidenceRef`, and verifier output as
|
|
185
|
-
`ProofBundle`.
|
|
194
|
+
`ProofBundle`. OpenLoops owns `WorkflowInvocation`, admission/work-item
|
|
195
|
+
queues, leases, workflow runs, retries, cancellation, worktrees, and run
|
|
196
|
+
artifacts.
|
|
197
|
+
- `open-events`: emit and replay validated event envelopes to channels.
|
|
198
|
+
OpenEvents delivers notifications only; it does not create workflow
|
|
199
|
+
invocations, own queue state, or retry agent work.
|
|
186
200
|
- `open-sessions`: convert messages/tool calls to `AgentTrajectory`, token
|
|
187
201
|
usage to `CostEstimate`, and transcript paths to `EvidenceRef`.
|
|
188
202
|
- `open-context`: serialize built context as `ContextPack` with citations as
|
|
@@ -202,10 +216,91 @@ native domain objects immediately.
|
|
|
202
216
|
- `open-actions`: keep domain action manifests, but expose shared `ActorRef`,
|
|
203
217
|
`EvidenceRef`, `CapabilityCard`, `DecisionEnvelope`, and `WorkRun` adapter
|
|
204
218
|
views.
|
|
219
|
+
- `open-automations`: keep deterministic app/product automation recipes and
|
|
220
|
+
connector/action recipes. Any agentic task, PR, review, or evaluation flow
|
|
221
|
+
must hand off to OpenLoops rather than creating a second workflow queue.
|
|
205
222
|
- `open-reports`: consume `ProofBundle`, `WorkRun`, `ContextPack`,
|
|
206
223
|
`CostEstimate`, and `EvidenceRef` to render compact Markdown/JSON/HTML proof
|
|
207
224
|
reports.
|
|
208
225
|
|
|
226
|
+
## WorkflowInvocation And App Storage Boundary
|
|
227
|
+
|
|
228
|
+
The canonical agent-work root is a `WorkflowInvocation`, not a todo task.
|
|
229
|
+
Only actionable unfinished work needs a todo. OpenTodos remains the
|
|
230
|
+
human-visible intent ledger; OpenLoops owns the durable workflow root,
|
|
231
|
+
admission queue, execution lifecycle, and canonical run artifacts.
|
|
232
|
+
|
|
233
|
+
A workflow invocation should carry these fields at the boundary:
|
|
234
|
+
|
|
235
|
+
- `id`
|
|
236
|
+
- `templateId` or `workflowId`
|
|
237
|
+
- `sourceRef`: a WorkflowInvocation-local source kind such as `task`, `event`,
|
|
238
|
+
`schedule`, `manual`, `pull_request`, `review`, or `knowledge`, plus an id
|
|
239
|
+
and dedupe key
|
|
240
|
+
- `subjectRef`: a WorkflowInvocation-local subject kind such as `repo`,
|
|
241
|
+
`pull_request`, `task`, `document`, `run`, or `metric`, plus a path, URL, or
|
|
242
|
+
id
|
|
243
|
+
- `intent`: `route`, `mutate`, `review`, `evaluate`, or `report`
|
|
244
|
+
- `scope`: project path, worktree policy, permissions, account policy, and
|
|
245
|
+
concurrency group
|
|
246
|
+
- `outputPolicy`: when to write reports and when to create a follow-up task
|
|
247
|
+
|
|
248
|
+
OpenLoops admission/work items are first-class records with route key,
|
|
249
|
+
idempotency key, source/subject refs, project key/group, priority, status,
|
|
250
|
+
attempts, next-attempt time, lease expiry, loop/workflow/run ids, and last
|
|
251
|
+
reason. Status values should be explicit: `queued`, `deferred`, `admitted`,
|
|
252
|
+
`running`, `succeeded`, `failed`, `dead_letter`, or `cancelled`.
|
|
253
|
+
|
|
254
|
+
Run artifacts live under:
|
|
255
|
+
|
|
256
|
+
```text
|
|
257
|
+
.hasna/loops/runs/<project-slug>/<subject-key>/<run-id>/manifest.json
|
|
258
|
+
.hasna/loops/runs/<project-slug>/<subject-key>/<run-id>/triage.md
|
|
259
|
+
.hasna/loops/runs/<project-slug>/<subject-key>/<run-id>/plan.md
|
|
260
|
+
.hasna/loops/runs/<project-slug>/<subject-key>/<run-id>/worker-report.md
|
|
261
|
+
.hasna/loops/runs/<project-slug>/<subject-key>/<run-id>/evaluation.md
|
|
262
|
+
.hasna/loops/runs/<project-slug>/<subject-key>/<run-id>/evidence/
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
The `<subject-key>` is never the raw subject reference. It must be a safe path
|
|
266
|
+
segment derived as `kind-safeSlug-shortHash`. Recommended normalization:
|
|
267
|
+
lowercase ASCII, replace non-alphanumeric runs with `-`, trim separators, cap
|
|
268
|
+
the slug portion at 72 characters, and append at least 12 hex characters from a
|
|
269
|
+
SHA-256 hash of the canonical raw `subjectRef`. Reject `.`/`..`, reserved device
|
|
270
|
+
names, path separators, empty keys, and path traversal. Store the raw
|
|
271
|
+
`subjectRef` only inside `manifest.json`.
|
|
272
|
+
|
|
273
|
+
OpenEvents webhooks/channels are notifications. A `task.created` notification
|
|
274
|
+
can be delivered through OpenEvents, but OpenLoops consumes the envelope and
|
|
275
|
+
upserts/admits work items. OpenEvents must not import OpenLoops or own
|
|
276
|
+
admission, retries, leases, verifier execution, or workflow run artifacts.
|
|
277
|
+
|
|
278
|
+
Every Hasna app stores local state under `.hasna/<app>/...`. The obsolete
|
|
279
|
+
`.hasna/apps/<app>` layout is not an operational read path. OpenKnowledge's
|
|
280
|
+
canonical storage is `.hasna/knowledge`, not `.hasna/apps/knowledge`.
|
|
281
|
+
|
|
282
|
+
No-backcompat migrations must preserve data without keeping legacy shims:
|
|
283
|
+
|
|
284
|
+
1. Create a read-only backup or export before moving data.
|
|
285
|
+
2. Atomically copy or rename into the canonical `.hasna/<app>` path.
|
|
286
|
+
3. Verify JSON item counts, SQLite integrity and table counts, artifact counts,
|
|
287
|
+
hashes, and any storage-object or sync-snapshot evidence.
|
|
288
|
+
4. Leave only a diagnostic tombstone at the old path.
|
|
289
|
+
5. Treat mismatched counts, hash failures, or SQLite integrity failures as
|
|
290
|
+
blockers.
|
|
291
|
+
|
|
292
|
+
Unattended automatic routes must fail closed when the configured sandbox cannot
|
|
293
|
+
be proven. Acceptable sandbox evidence includes a successful preflight receipt
|
|
294
|
+
that names the isolation provider, filesystem/network policy, writable roots,
|
|
295
|
+
tool allowlist, environment redaction result, and timestamp for the exact route
|
|
296
|
+
or run. `danger-full-access` plus a worktree is a manual break-glass mode, not a
|
|
297
|
+
safe auto-route default.
|
|
298
|
+
|
|
299
|
+
`WorkflowInvocation` is documented here as the architecture boundary used by
|
|
300
|
+
OpenLoops and neighboring packages. It is not yet a wire schema in the current
|
|
301
|
+
catalog; add a `hasna.workflow_invocation.v1` schema only when at least two
|
|
302
|
+
packages need to validate the object directly at a shared boundary.
|
|
303
|
+
|
|
209
304
|
## Enforcement Model
|
|
210
305
|
|
|
211
306
|
Validate at every boundary where another package, agent, process, or machine can
|
package/dist/cli/index.js
CHANGED
|
@@ -992,7 +992,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
992
992
|
this._exitCallback = (err) => {
|
|
993
993
|
if (err.code !== "commander.executeSubCommandAsync") {
|
|
994
994
|
throw err;
|
|
995
|
-
}
|
|
995
|
+
} else {}
|
|
996
996
|
};
|
|
997
997
|
}
|
|
998
998
|
return this;
|
|
@@ -6074,7 +6074,7 @@ var coerce = {
|
|
|
6074
6074
|
};
|
|
6075
6075
|
var NEVER = INVALID;
|
|
6076
6076
|
// src/schemas.ts
|
|
6077
|
-
var CONTRACTS_PACKAGE_VERSION = "0.1.
|
|
6077
|
+
var CONTRACTS_PACKAGE_VERSION = "0.1.1";
|
|
6078
6078
|
var SCHEMA_IDS = {
|
|
6079
6079
|
actorRef: "hasna.actor_ref.v1",
|
|
6080
6080
|
resourceRef: "hasna.resource_ref.v1",
|
package/dist/index.js
CHANGED
|
@@ -3989,7 +3989,7 @@ var coerce = {
|
|
|
3989
3989
|
var NEVER = INVALID;
|
|
3990
3990
|
// src/schemas.ts
|
|
3991
3991
|
var CONTRACTS_PACKAGE_NAME = "@hasna/contracts";
|
|
3992
|
-
var CONTRACTS_PACKAGE_VERSION = "0.1.
|
|
3992
|
+
var CONTRACTS_PACKAGE_VERSION = "0.1.1";
|
|
3993
3993
|
var SCHEMA_IDS = {
|
|
3994
3994
|
actorRef: "hasna.actor_ref.v1",
|
|
3995
3995
|
resourceRef: "hasna.resource_ref.v1",
|
package/dist/schemas.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
export declare const CONTRACTS_PACKAGE_NAME = "@hasna/contracts";
|
|
3
|
-
export declare const CONTRACTS_PACKAGE_VERSION = "0.1.
|
|
3
|
+
export declare const CONTRACTS_PACKAGE_VERSION = "0.1.1";
|
|
4
4
|
export declare const SCHEMA_IDS: {
|
|
5
5
|
readonly actorRef: "hasna.actor_ref.v1";
|
|
6
6
|
readonly resourceRef: "hasna.resource_ref.v1";
|
package/dist/schemas.js
CHANGED
|
@@ -3989,7 +3989,7 @@ var coerce = {
|
|
|
3989
3989
|
var NEVER = INVALID;
|
|
3990
3990
|
// src/schemas.ts
|
|
3991
3991
|
var CONTRACTS_PACKAGE_NAME = "@hasna/contracts";
|
|
3992
|
-
var CONTRACTS_PACKAGE_VERSION = "0.1.
|
|
3992
|
+
var CONTRACTS_PACKAGE_VERSION = "0.1.1";
|
|
3993
3993
|
var SCHEMA_IDS = {
|
|
3994
3994
|
actorRef: "hasna.actor_ref.v1",
|
|
3995
3995
|
resourceRef: "hasna.resource_ref.v1",
|
package/dist/validators.js
CHANGED
|
@@ -3989,7 +3989,7 @@ var coerce = {
|
|
|
3989
3989
|
var NEVER = INVALID;
|
|
3990
3990
|
// src/schemas.ts
|
|
3991
3991
|
var CONTRACTS_PACKAGE_NAME = "@hasna/contracts";
|
|
3992
|
-
var CONTRACTS_PACKAGE_VERSION = "0.1.
|
|
3992
|
+
var CONTRACTS_PACKAGE_VERSION = "0.1.1";
|
|
3993
3993
|
var SCHEMA_IDS = {
|
|
3994
3994
|
actorRef: "hasna.actor_ref.v1",
|
|
3995
3995
|
resourceRef: "hasna.resource_ref.v1",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/contracts",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Shared schemas and validators for Hasna open-source agent infrastructure contracts.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"lint": "tsc --noEmit",
|
|
48
48
|
"verify:release": "bun run typecheck && bun test && bun run build && bun run smoke:dist && bun run pack:check",
|
|
49
49
|
"smoke:dist": "bun scripts/smoke-dist.ts",
|
|
50
|
-
"pack:check": "
|
|
50
|
+
"pack:check": "bun pm pack --dry-run --ignore-scripts",
|
|
51
51
|
"dev:cli": "bun run src/cli/index.ts",
|
|
52
52
|
"prepack": "bun run verify:release",
|
|
53
53
|
"prepublishOnly": "bun run typecheck && bun test"
|