@a-company/gnomon 0.0.0-stage → 8.0.2

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 (71) hide show
  1. package/README.md +126 -2
  2. package/dist/agent.d.ts +28 -0
  3. package/dist/agent.js +45708 -0
  4. package/dist/build-id.json +1 -0
  5. package/dist/cli/gnomon.js +53946 -0
  6. package/dist/cli/gnomond.js +47744 -0
  7. package/dist/gnomon-local/cli.js +897 -0
  8. package/dist/index.d.ts +3477 -0
  9. package/dist/index.js +13698 -0
  10. package/dist/loops.d.ts +440 -0
  11. package/dist/loops.js +4706 -0
  12. package/dist/signer-CQ3Bpe7G.d.ts +158 -0
  13. package/dist/transport/gnomon-web.js +688 -0
  14. package/gnomon-mods/.purpose +143 -0
  15. package/gnomon-mods/constellation/README.md +27 -0
  16. package/gnomon-mods/constellation/fixtures/map-the-idea.golden.json +19 -0
  17. package/gnomon-mods/constellation/fixtures/map-the-idea.json +3 -0
  18. package/gnomon-mods/constellation/fixtures/summarize-the-session.golden.json +20 -0
  19. package/gnomon-mods/constellation/fixtures/summarize-the-session.json +3 -0
  20. package/gnomon-mods/constellation/fixtures/two-blocks.golden.json +4 -0
  21. package/gnomon-mods/constellation/fixtures/two-blocks.json +3 -0
  22. package/gnomon-mods/constellation/gnomon-manifest.json +68 -0
  23. package/gnomon-mods/constellation/skills/constellation-desk/SKILL.md +35 -0
  24. package/gnomon-mods/ledger/README.md +10 -0
  25. package/gnomon-mods/ledger/fixtures/breaker.golden.json +28 -0
  26. package/gnomon-mods/ledger/fixtures/breaker.json +80 -0
  27. package/gnomon-mods/ledger/fixtures/compacted.golden.json +42 -0
  28. package/gnomon-mods/ledger/fixtures/compacted.json +103 -0
  29. package/gnomon-mods/ledger/fixtures/over-budget.golden.json +24 -0
  30. package/gnomon-mods/ledger/fixtures/over-budget.json +86 -0
  31. package/gnomon-mods/ledger/fixtures/strip-reduced.golden.json +23 -0
  32. package/gnomon-mods/ledger/fixtures/strip-reduced.json +76 -0
  33. package/gnomon-mods/ledger/fixtures/strip.golden.json +18 -0
  34. package/gnomon-mods/ledger/fixtures/strip.json +68 -0
  35. package/gnomon-mods/ledger/gnomon-manifest.json +16 -0
  36. package/gnomon-mods/ledger/index.mjs +77 -0
  37. package/gnomon-mods/ledger/model.mjs +237 -0
  38. package/gnomon-mods/neurons/README.md +31 -0
  39. package/gnomon-mods/neurons/fixtures/capture-a-decision.golden.json +20 -0
  40. package/gnomon-mods/neurons/fixtures/capture-a-decision.json +3 -0
  41. package/gnomon-mods/neurons/fixtures/capture-a-learning.golden.json +19 -0
  42. package/gnomon-mods/neurons/fixtures/capture-a-learning.json +3 -0
  43. package/gnomon-mods/neurons/fixtures/search-the-brain.golden.json +19 -0
  44. package/gnomon-mods/neurons/fixtures/search-the-brain.json +3 -0
  45. package/gnomon-mods/neurons/fixtures/undeclared-kind.golden.json +9 -0
  46. package/gnomon-mods/neurons/fixtures/undeclared-kind.json +3 -0
  47. package/gnomon-mods/neurons/gnomon-manifest.json +87 -0
  48. package/gnomon-mods/neurons/skills/neurons-desk/SKILL.md +44 -0
  49. package/gnomon-mods/paradigm-context/README.md +9 -0
  50. package/gnomon-mods/paradigm-context/fixtures/empty.golden.json +28 -0
  51. package/gnomon-mods/paradigm-context/fixtures/empty.json +48 -0
  52. package/gnomon-mods/paradigm-context/fixtures/full-dark.golden.json +497 -0
  53. package/gnomon-mods/paradigm-context/fixtures/full-dark.json +134 -0
  54. package/gnomon-mods/paradigm-context/fixtures/full.golden.json +497 -0
  55. package/gnomon-mods/paradigm-context/fixtures/full.json +134 -0
  56. package/gnomon-mods/paradigm-context/fixtures/stale.golden.json +205 -0
  57. package/gnomon-mods/paradigm-context/fixtures/stale.json +69 -0
  58. package/gnomon-mods/paradigm-context/fixtures/unfocused.golden.json +28 -0
  59. package/gnomon-mods/paradigm-context/fixtures/unfocused.json +14 -0
  60. package/gnomon-mods/paradigm-context/gnomon-manifest.json +15 -0
  61. package/gnomon-mods/paradigm-context/index.mjs +64 -0
  62. package/gnomon-mods/paradigm-context/model.mjs +137 -0
  63. package/gnomon-mods/workshop/README.md +12 -0
  64. package/gnomon-mods/workshop/fixtures/strip-reduced.golden.json +56 -0
  65. package/gnomon-mods/workshop/fixtures/strip-reduced.json +16 -0
  66. package/gnomon-mods/workshop/fixtures/strip.golden.json +56 -0
  67. package/gnomon-mods/workshop/fixtures/strip.json +16 -0
  68. package/gnomon-mods/workshop/gnomon-manifest.json +14 -0
  69. package/gnomon-mods/workshop/index.mjs +73 -0
  70. package/gnomon-mods/workshop/model.mjs +152 -0
  71. package/package.json +80 -4
@@ -0,0 +1,158 @@
1
+ import { KeyObject } from 'node:crypto';
2
+
3
+ /**
4
+ * @symbol #kernel-log
5
+ *
6
+ * #kernel-log (spec §3.1 key classes + signature domains, §3.2 "Signatures and
7
+ * anchors") — the `Signer` seam and the key ring the verifier uses.
8
+ *
9
+ * THE SEAM. Every signature the log writes goes through `Signer.sign(domain,
10
+ * message)`. The signer, not the caller, prepends the domain, so a signature
11
+ * made for one purpose can never verify for another (domain separation):
12
+ *
13
+ * preimage = utf8(<domain> + "\n" + <message>)
14
+ *
15
+ * with the §3.1 domains `gnomon:event-sig:v1`, `gnomon:row-sig:v1`,
16
+ * `gnomon:approve:v1`, `gnomon:approve-voice:v1`, `gnomon:auth:v1` and
17
+ * `gnomon:brief:v1`. For an event, `message` is the event's tagged hash
18
+ * (`sha256:<hex>`), so the signature commits to the whole envelope.
19
+ *
20
+ * Each key class may sign only its own domains (§3.1): the kernel key signs
21
+ * events, `hello` serverSig (`gnomon:auth-server:v2`, M1.4 — never the client
22
+ * `gnomon:auth:v1` domain, so the kernel is no signing oracle for client
23
+ * transcripts) and briefs; the root key signs rows
24
+ * (registry, grants, config, install); the approvals key signs decisions.
25
+ *
26
+ * PR-4 ships ONE implementation: `SoftwareEd25519Signer`, the kernel key held
27
+ * in kernel memory. In production the key material comes from the OS keystore
28
+ * item `gnomon-kernel-key` via the signed helper (§3.1); until probes P04
29
+ * (Secure Enclave / helper) and P02 land, a caller hands the PEM in. The root
30
+ * and approvals keys are HARDWARE P-256 and never software (§3.1 failure
31
+ * modes: "never a software fallback, never a file") — their signers plug in
32
+ * behind this same interface after P04/P02. The key ring already VERIFIES
33
+ * `gkey-p256:v1` signatures (ECDSA P-256 / SHA-256, IEEE-P1363 encoding) so
34
+ * those rows verify the day they appear.
35
+ *
36
+ * The interface is synchronous because the kernel key lives in kernel memory
37
+ * (§3.1 "loaded into kernel memory at daemon start") and append runs inside a
38
+ * write transaction. A hardware signer is asynchronous (helper XPC); it will
39
+ * get an async append path that serializes on the chain tip — deferred with
40
+ * the hardware signers.
41
+ */
42
+
43
+ /** The §3.1 signature domains (the prefix before the first `\n`). */
44
+ declare const SIGNATURE_DOMAINS: {
45
+ readonly event: "gnomon:event-sig:v1";
46
+ readonly row: "gnomon:row-sig:v1";
47
+ readonly approve: "gnomon:approve:v1";
48
+ readonly approveVoice: "gnomon:approve-voice:v1";
49
+ /** The three auth domains come FROM the contracts constants (P8-D93 round 3): one definition, in clientApiId. */
50
+ readonly auth: "gnomon:auth:v1";
51
+ /** #socket serverSig (§4.9): `gnomon:auth-server:v2\n` + contracts authServerMessage (nonce, clientNonce, endpointPath, negotiated hello; v2 since P8-D93), kernel key only. */
52
+ readonly authServer: "gnomon:auth-server:v2";
53
+ /** Read-token proof of possession (§4.9, P8-D89a): the token's own Ed25519 key only. */
54
+ readonly authToken: "gnomon:auth-token:v1";
55
+ readonly brief: "gnomon:brief:v1";
56
+ /**
57
+ * #approval-broker (M1.6): the kernel key signs `card.actions[]` and the
58
+ * presence-prompt record (§3.1 kernel key "Signs:"). The spec names no
59
+ * domain string for either; these two are kernel-internal (not in
60
+ * clientApiId) and keep both apart from event signatures.
61
+ */
62
+ readonly cardAction: "gnomon:card-action:v1";
63
+ readonly presencePrompt: "gnomon:presence-prompt:v1";
64
+ /** #budget-fuse (M1.6): the kernel key signs every permit:v1 (§4.8 `sig`); kernel-internal domain. */
65
+ readonly permit: "gnomon:permit:v1";
66
+ /**
67
+ * #identity (M1.3): a hardware presence attestation — the approvals key
68
+ * (Secure Enclave, behind the signed helper; never the root, round 2 M1) signs a kernel challenge
69
+ * `<purpose>\n<bindingDigest>\n<connId>\n<challenge>` after the helper's
70
+ * presence prompt; the presence module mints a PresenceToken only on a
71
+ * verified one. Kernel-internal (not in clientApiId).
72
+ */
73
+ readonly presence: "gnomon:presence:v1";
74
+ };
75
+ type SignatureDomain = keyof typeof SIGNATURE_DOMAINS;
76
+ /** §3.1 key classes that sign (the link key never signs; X25519, Noise only). */
77
+ type KeyClass = 'kernel' | 'root' | 'approvals' | 'device' | 'agent' | 'readToken';
78
+ /** Which domains each key class may sign (§3.1 "Signs:" per class). */
79
+ declare const DOMAINS_BY_KEY_CLASS: Readonly<Record<KeyClass, readonly SignatureDomain[]>>;
80
+ type KeyCustody = 'software' | 'hardware';
81
+ interface Signer {
82
+ /** `gkey:v1:<sha256(normalized spki PEM)>` (Ed25519) or `gkey-p256:v1:…`. */
83
+ readonly keyId: string;
84
+ readonly keyClass: KeyClass;
85
+ readonly custody: KeyCustody;
86
+ /** Sign `domain + "\n" + message`; throws if this key class may not sign the domain. */
87
+ sign(domain: SignatureDomain, message: string): Uint8Array;
88
+ }
89
+ /** The exact bytes a signature covers. */
90
+ declare function signaturePreimage(domain: SignatureDomain, message: string): Buffer;
91
+ /** The approve-domain message (§3.1): approver in the preimage (Q5). */
92
+ declare function approveMessage(f: {
93
+ cardId: string;
94
+ decision: string;
95
+ cardContentHash: string;
96
+ approverPrincipalId: string;
97
+ }): string;
98
+ /**
99
+ * #approval-broker decisionSig v2 (P8-D98, TD-2026-10-19-648, slice A2). The v2 layout (contracts
100
+ * decisionMessageV2) adds the answer digest, so a typed `answer{text}` binds the text the human approved:
101
+ * gnomon:decision:v2 \n cardId \n decision \n cardContentHash \n approverPrincipalId \n answerDigest
102
+ * It is used ONLY for the DECISION_SIG_V2_DECISIONS (`answer`); every other decision keeps the v1
103
+ * approveMessage. The domain stays `gnomon:approve:v1`: the version lives in the message's first line.
104
+ */
105
+ declare function usesDecisionV2(decision: string): boolean;
106
+ /** sha256:<hex> of the UTF-8 answer text (the same bytes approval.decide records as noteHash). */
107
+ declare function answerDigest(text: string): string;
108
+ /**
109
+ * The decisionSig message for a decision: v2 for `answer` (answerDigest REQUIRED; a missing one throws,
110
+ * never a silent v1), v1 approveMessage otherwise (an answerDigest on a v1 decision throws: no ambiguity).
111
+ */
112
+ declare function decisionMessage(f: {
113
+ cardId: string;
114
+ decision: string;
115
+ cardContentHash: string;
116
+ approverPrincipalId: string;
117
+ answerDigest?: string;
118
+ /** TD-2026-10-20-294: a prefix-scoped `always` signs v2 with the scope digest as its last line */
119
+ scopeDigest?: string;
120
+ }): string;
121
+ /** keyId for an Ed25519 public key: `gkey:v1:` + sha256(normalized spki PEM). */
122
+ declare function ed25519KeyId(publicKeyPem: string): string;
123
+ /** keyId for a P-256 public key: `gkey-p256:v1:` + sha256(spki DER). */
124
+ declare function p256KeyId(publicKey: KeyObject): string;
125
+ declare class SignerDomainError extends Error {
126
+ constructor(keyClass: KeyClass, domain: SignatureDomain);
127
+ }
128
+ /**
129
+ * The software Ed25519 signer — the kernel key held in memory (PR-4). Also the
130
+ * shape device and agent keys take (they are Ed25519 files, §3.1). Refuses to
131
+ * be constructed as a root or approvals key: those are hardware-only.
132
+ */
133
+ declare class SoftwareEd25519Signer implements Signer {
134
+ #private;
135
+ readonly keyId: string;
136
+ readonly keyClass: KeyClass;
137
+ readonly custody: "software";
138
+ readonly publicKeyPem: string;
139
+ constructor(privateKeyPem: string, keyClass?: KeyClass);
140
+ /** A fresh in-memory kernel key (tests; production loads from the keystore). */
141
+ static generate(keyClass?: KeyClass): SoftwareEd25519Signer;
142
+ sign(domain: SignatureDomain, message: string): Uint8Array;
143
+ }
144
+ /**
145
+ * Public keys by keyId, for verification. M1.3 (#identity) fills it from the
146
+ * root-signed registry; PR-4 callers add keys directly. Never throws on
147
+ * malformed input: a bad signature or unknown key is simply `false`/`unknown`.
148
+ */
149
+ declare class KeyRing {
150
+ #private;
151
+ addEd25519(publicKeyPem: string): string;
152
+ addP256(publicKey: KeyObject | string): string;
153
+ has(keyId: string): boolean;
154
+ verify(keyId: string, domain: SignatureDomain, message: string, sig: Uint8Array): 'ok' | 'bad' | 'unknown-key';
155
+ }
156
+
157
+ export { DOMAINS_BY_KEY_CLASS as D, KeyRing as K, SIGNATURE_DOMAINS as c, SignerDomainError as e, SoftwareEd25519Signer as f, answerDigest as g, approveMessage as h, decisionMessage as i, ed25519KeyId as j, p256KeyId as p, signaturePreimage as s, usesDecisionV2 as u };
158
+ export type { Signer as S, KeyClass as a, KeyCustody as b, SignatureDomain as d };