@finchip.ai/foga 0.0.0-stage → 0.6.0-alpha.4
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/LICENSE +201 -0
- package/NOTICE +21 -0
- package/README.md +216 -2
- package/artifacts/bundle.json +74250 -0
- package/artifacts/bundle.sha256 +1 -0
- package/bin/foga.js +14 -0
- package/build/known-interface-ids.json +18 -0
- package/build/profiles.json +120 -0
- package/dist/build/bundle.js +417 -0
- package/dist/build/vendor.js +74 -0
- package/dist/bundle/load.js +24 -0
- package/dist/bundle/types.js +1 -0
- package/dist/cli-cell.js +395 -0
- package/dist/cli.js +505 -0
- package/dist/core/acdf.js +162 -0
- package/dist/core/adrf.js +273 -0
- package/dist/core/aid.js +83 -0
- package/dist/core/ard.js +146 -0
- package/dist/core/asf.js +157 -0
- package/dist/core/canonical.js +79 -0
- package/dist/core/erc8004.js +52 -0
- package/dist/core/kya.js +225 -0
- package/dist/core/measure.js +96 -0
- package/dist/core/pack/cbor.js +130 -0
- package/dist/core/pack/skillpack.js +142 -0
- package/dist/core/skills.js +40 -0
- package/dist/core/swarm.js +206 -0
- package/dist/core/tenders.js +121 -0
- package/dist/core/units.js +122 -0
- package/dist/core/world.js +104 -0
- package/dist/demo/demander.js +76 -0
- package/dist/demo/evidence.js +1 -0
- package/dist/demo/loop-d.js +449 -0
- package/dist/doctor/checks.js +51 -0
- package/dist/doctor/doctor.js +385 -0
- package/dist/doctor/loop-d.js +103 -0
- package/dist/doctor/probe.js +97 -0
- package/dist/doctor/semantic.js +83 -0
- package/dist/genesis/extract.js +64 -0
- package/dist/genesis/funding.js +126 -0
- package/dist/genesis/operator-scope.js +90 -0
- package/dist/genesis/preflight.js +54 -0
- package/dist/genesis/probe.js +164 -0
- package/dist/genesis/roles.js +96 -0
- package/dist/genesis/run.js +71 -0
- package/dist/genesis/scenario.js +765 -0
- package/dist/genesis/skill-runner.js +103 -0
- package/dist/genesis/skill-worker.js +41 -0
- package/dist/genesis/t1-zk.js +62 -0
- package/dist/genesis/t3-zk.js +105 -0
- package/dist/genesis/t4.js +259 -0
- package/dist/genesis/t5.js +168 -0
- package/dist/genesis/t6.js +222 -0
- package/dist/genesis/t7.js +198 -0
- package/dist/genesis/t8.js +189 -0
- package/dist/genesis/t9.js +188 -0
- package/dist/genesis/zk.js +128 -0
- package/dist/http/server.js +276 -0
- package/dist/kernel/cell.js +104 -0
- package/dist/kernel/errors.js +78 -0
- package/dist/kernel/kernel.js +251 -0
- package/dist/kernel/provider.js +125 -0
- package/dist/kernel/store.js +470 -0
- package/dist/kernel/tx.js +385 -0
- package/dist/mcp/server.js +170 -0
- package/dist/node/config.js +195 -0
- package/dist/node/init.js +200 -0
- package/dist/node/keys.js +95 -0
- package/dist/node/migrate.js +173 -0
- package/dist/node/model/anthropic.js +97 -0
- package/dist/node/model/stub.js +129 -0
- package/dist/node/model/types.js +9 -0
- package/dist/node/node.js +198 -0
- package/dist/node/policy.js +95 -0
- package/dist/node/runner.js +256 -0
- package/dist/node/watchers.js +88 -0
- package/dist/tools/admin.js +184 -0
- package/dist/tools/catalog.js +261 -0
- package/dist/tools/common.js +143 -0
- package/dist/tools/identity.js +107 -0
- package/dist/tools/index.js +14 -0
- package/dist/tools/read.js +471 -0
- package/dist/tools/tenders.js +400 -0
- package/dist/tools/types.js +4 -0
- package/dist/util/bytecode.js +123 -0
- package/dist/util/fs.js +58 -0
- package/dist/util/hash.js +4 -0
- package/dist/util/log.js +11 -0
- package/dist/util/version.js +12 -0
- package/dist/world/deploy.js +277 -0
- package/dist/world/plan.js +93 -0
- package/dist/world/types.js +1 -0
- package/docs/build.md +45 -0
- package/docs/cell-account.md +58 -0
- package/docs/compatibility-matrix.md +38 -0
- package/docs/design-memo.md +113 -0
- package/docs/doctor.md +53 -0
- package/docs/examples/README.md +11 -0
- package/docs/examples/claude-code-mcp.json +13 -0
- package/docs/examples/claude_desktop_config.json +12 -0
- package/docs/examples/cursor-mcp.json +11 -0
- package/docs/genesis.md +312 -0
- package/docs/kernel.md +101 -0
- package/docs/loop-d.md +90 -0
- package/docs/mcp.md +105 -0
- package/docs/node.md +66 -0
- package/docs/version-lock.md +67 -0
- package/docs/world.md +50 -0
- package/docs/zk.md +48 -0
- package/package.json +82 -4
- package/prover/README.md +26 -0
- package/prover/build-predicate.mjs +77 -0
- package/prover/package-lock.json +1837 -0
- package/prover/package.json +15 -0
- package/prover/run.cjs +199 -0
- package/scenarios/fixtures/sample-filing.txt +16 -0
- package/scenarios/skills/finch-extract-verify/LICENSE +2 -0
- package/scenarios/skills/finch-extract-verify/SKILL.md +34 -0
- package/scenarios/skills/finch-extract-verify/fields.json +56 -0
- package/scenarios/skills/finch-extract-verify/manifest.json +16 -0
- package/scenarios/skills/foga-probe/LICENSE +2 -0
- package/scenarios/skills/foga-probe/SKILL.md +35 -0
- package/scenarios/skills/foga-probe/manifest.json +16 -0
- package/scenarios/skills/foga-probe/probe.schema.json +40 -0
- package/server.json +79 -0
- package/vendor/LOCK.json +107 -0
- package/vendor/README.md +13 -0
- package/worlds/local.json +34 -0
- package/worlds/sepolia.json +314 -0
- package/zk/build/verification_key.json +174 -0
- package/zk/circuits/kya_predicate_count_v1.circom +231 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
pragma circom 2.1.6;
|
|
2
|
+
|
|
3
|
+
// FOGA predicate-pattern ZK-KYA circuit, revision 1: `kya-predicate-count-v1`.
|
|
4
|
+
//
|
|
5
|
+
// Statement proved (the SUBJECT is public; the records and their source are not):
|
|
6
|
+
// "Among at most N task-completion records signed by one source whose key is a member of the source set
|
|
7
|
+
// committed to by `sourceSetRoot`, at least K concern `subjectKey`, carry status Accepted (1) and a
|
|
8
|
+
// timestamp inside [t0, t1]; the records are distinct. result = 1 when the count reaches K. My nullifier
|
|
9
|
+
// for (schemeId, admissionDomain, epoch, challenge) is Poseidon(secret, schemeId, admissionDomain, epoch,
|
|
10
|
+
// challenge)."
|
|
11
|
+
//
|
|
12
|
+
// This is the predicate pattern of ZK-KYA (ERC-8419 section 5): the scheme is the decision rule, and the
|
|
13
|
+
// prover evaluates it over data authenticated by its source. The chain learns the subject, the rule's
|
|
14
|
+
// parameters (window, K, source set) and the result bit; never which records, how many, or their content.
|
|
15
|
+
// It proves a fact about a range of records, not that the agent is trustworthy.
|
|
16
|
+
//
|
|
17
|
+
// Conventions shared with the upstream `kya_public_v1` circuit: 256-bit values travel as (hi128, lo128);
|
|
18
|
+
// `schemeId` and `admissionDomain` are fed by the on-chain adapter from its own arguments, never chosen by
|
|
19
|
+
// the prover; `epoch` is enforced by the adapter against block time within a grace window.
|
|
20
|
+
//
|
|
21
|
+
// Public signals (snarkjs order: outputs first, then public inputs in declaration order):
|
|
22
|
+
// [0] nullifierHi (output) [1] nullifierLo (output) [2] result (output)
|
|
23
|
+
// [3] subjectKeyHi [4] subjectKeyLo [5] challengeHi [6] challengeLo
|
|
24
|
+
// [7] t0 [8] t1 [9] k [10] sourceSetRootHi [11] sourceSetRootLo
|
|
25
|
+
// [12] schemeIdHi [13] schemeIdLo [14] epoch [15] admissionDomainHi [16] admissionDomainLo
|
|
26
|
+
//
|
|
27
|
+
// The committed build instantiates N = 8 record slots and a source set of depth 16 (about 87k constraints,
|
|
28
|
+
// powers of tau 2^17); N and the depth are template parameters.
|
|
29
|
+
//
|
|
30
|
+
// A record is (subjectKeyHi, subjectKeyLo, taskRef, status, timestamp) with taskRef a 128-bit identifier of
|
|
31
|
+
// the completion (the source's own hash of chain, task contract, token and submission); the source signs
|
|
32
|
+
// Poseidon(5) of those fields with EdDSA over Baby Jubjub. Slots are filled from index 0 without gaps;
|
|
33
|
+
// present records carry strictly increasing taskRefs, so no record counts twice.
|
|
34
|
+
|
|
35
|
+
include "circomlib/circuits/poseidon.circom";
|
|
36
|
+
include "circomlib/circuits/eddsaposeidon.circom";
|
|
37
|
+
include "circomlib/circuits/bitify.circom";
|
|
38
|
+
include "circomlib/circuits/comparators.circom";
|
|
39
|
+
include "circomlib/circuits/mux1.circom";
|
|
40
|
+
|
|
41
|
+
template Split128() {
|
|
42
|
+
signal input in;
|
|
43
|
+
signal output hi;
|
|
44
|
+
signal output lo;
|
|
45
|
+
component n2b = Num2Bits_strict();
|
|
46
|
+
n2b.in <== in;
|
|
47
|
+
component loB = Bits2Num(128);
|
|
48
|
+
component hiB = Bits2Num(126);
|
|
49
|
+
for (var i = 0; i < 128; i++) loB.in[i] <== n2b.out[i];
|
|
50
|
+
for (var i = 0; i < 126; i++) hiB.in[i] <== n2b.out[128 + i];
|
|
51
|
+
hi <== hiB.out;
|
|
52
|
+
lo <== loB.out;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
template MerkleInclusion(levels) {
|
|
56
|
+
signal input leaf;
|
|
57
|
+
signal input pathElements[levels];
|
|
58
|
+
signal input pathIndices[levels];
|
|
59
|
+
signal output root;
|
|
60
|
+
|
|
61
|
+
component hashers[levels];
|
|
62
|
+
component mux[levels];
|
|
63
|
+
signal cur[levels + 1];
|
|
64
|
+
cur[0] <== leaf;
|
|
65
|
+
for (var i = 0; i < levels; i++) {
|
|
66
|
+
pathIndices[i] * (1 - pathIndices[i]) === 0;
|
|
67
|
+
mux[i] = MultiMux1(2);
|
|
68
|
+
mux[i].c[0][0] <== cur[i];
|
|
69
|
+
mux[i].c[0][1] <== pathElements[i];
|
|
70
|
+
mux[i].c[1][0] <== pathElements[i];
|
|
71
|
+
mux[i].c[1][1] <== cur[i];
|
|
72
|
+
mux[i].s <== pathIndices[i];
|
|
73
|
+
hashers[i] = Poseidon(2);
|
|
74
|
+
hashers[i].inputs[0] <== mux[i].out[0];
|
|
75
|
+
hashers[i].inputs[1] <== mux[i].out[1];
|
|
76
|
+
cur[i + 1] <== hashers[i].out;
|
|
77
|
+
}
|
|
78
|
+
root <== cur[levels];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
template KYAPredicateCountV1(n, depth) {
|
|
82
|
+
// ---- public inputs ----
|
|
83
|
+
signal input subjectKeyHi;
|
|
84
|
+
signal input subjectKeyLo;
|
|
85
|
+
signal input challengeHi;
|
|
86
|
+
signal input challengeLo;
|
|
87
|
+
signal input t0;
|
|
88
|
+
signal input t1;
|
|
89
|
+
signal input k;
|
|
90
|
+
signal input sourceSetRootHi;
|
|
91
|
+
signal input sourceSetRootLo;
|
|
92
|
+
signal input schemeIdHi;
|
|
93
|
+
signal input schemeIdLo;
|
|
94
|
+
signal input epoch;
|
|
95
|
+
signal input admissionDomainHi;
|
|
96
|
+
signal input admissionDomainLo;
|
|
97
|
+
|
|
98
|
+
// ---- private inputs ----
|
|
99
|
+
signal input secret;
|
|
100
|
+
signal input Ax; // the source's EdDSA (Baby Jubjub) public key
|
|
101
|
+
signal input Ay;
|
|
102
|
+
signal input pathElements[depth]; // the source's membership in the source set
|
|
103
|
+
signal input pathIndices[depth];
|
|
104
|
+
signal input present[n]; // 1 for a filled slot, 0 for an empty one; filled slots first
|
|
105
|
+
signal input taskRef[n]; // 128-bit record identifiers, strictly increasing over filled slots
|
|
106
|
+
signal input status[n]; // 1 = Accepted
|
|
107
|
+
signal input timestamp[n]; // seconds, 64-bit
|
|
108
|
+
signal input S[n]; // the source's signature over each record
|
|
109
|
+
signal input R8x[n];
|
|
110
|
+
signal input R8y[n];
|
|
111
|
+
|
|
112
|
+
// ---- outputs ----
|
|
113
|
+
signal output nullifierHi;
|
|
114
|
+
signal output nullifierLo;
|
|
115
|
+
signal output result;
|
|
116
|
+
|
|
117
|
+
// range sanity on public fields
|
|
118
|
+
component skh = Num2Bits(128); skh.in <== subjectKeyHi;
|
|
119
|
+
component skl = Num2Bits(128); skl.in <== subjectKeyLo;
|
|
120
|
+
component chh = Num2Bits(128); chh.in <== challengeHi;
|
|
121
|
+
component chl = Num2Bits(128); chl.in <== challengeLo;
|
|
122
|
+
component sih = Num2Bits(128); sih.in <== schemeIdHi;
|
|
123
|
+
component sil = Num2Bits(128); sil.in <== schemeIdLo;
|
|
124
|
+
component adh = Num2Bits(128); adh.in <== admissionDomainHi;
|
|
125
|
+
component adl = Num2Bits(128); adl.in <== admissionDomainLo;
|
|
126
|
+
component t0b = Num2Bits(64); t0b.in <== t0;
|
|
127
|
+
component t1b = Num2Bits(64); t1b.in <== t1;
|
|
128
|
+
component kb = Num2Bits(16); kb.in <== k;
|
|
129
|
+
component epb = Num2Bits(64); epb.in <== epoch;
|
|
130
|
+
|
|
131
|
+
// the source is a member of the source set
|
|
132
|
+
component leaf = Poseidon(2);
|
|
133
|
+
leaf.inputs[0] <== Ax;
|
|
134
|
+
leaf.inputs[1] <== Ay;
|
|
135
|
+
component inc = MerkleInclusion(depth);
|
|
136
|
+
inc.leaf <== leaf.out;
|
|
137
|
+
for (var i = 0; i < depth; i++) {
|
|
138
|
+
inc.pathElements[i] <== pathElements[i];
|
|
139
|
+
inc.pathIndices[i] <== pathIndices[i];
|
|
140
|
+
}
|
|
141
|
+
component rootSplit = Split128();
|
|
142
|
+
rootSplit.in <== inc.root;
|
|
143
|
+
rootSplit.hi === sourceSetRootHi;
|
|
144
|
+
rootSplit.lo === sourceSetRootLo;
|
|
145
|
+
|
|
146
|
+
// the records: signed by the source, about the subject, counted when Accepted inside the window
|
|
147
|
+
component msg[n];
|
|
148
|
+
component sig[n];
|
|
149
|
+
component refBits[n];
|
|
150
|
+
component tsBits[n];
|
|
151
|
+
component geT0[n];
|
|
152
|
+
component leT1[n];
|
|
153
|
+
component isAccepted[n];
|
|
154
|
+
component increasing[n];
|
|
155
|
+
signal counted[n];
|
|
156
|
+
signal inWindow[n];
|
|
157
|
+
signal acceptedPresent[n];
|
|
158
|
+
signal acc[n + 1];
|
|
159
|
+
acc[0] <== 0;
|
|
160
|
+
|
|
161
|
+
for (var i = 0; i < n; i++) {
|
|
162
|
+
present[i] * (1 - present[i]) === 0;
|
|
163
|
+
if (i > 0) {
|
|
164
|
+
// filled slots come first: present[i] <= present[i-1]
|
|
165
|
+
present[i] * (1 - present[i - 1]) === 0;
|
|
166
|
+
}
|
|
167
|
+
refBits[i] = Num2Bits(128); refBits[i].in <== taskRef[i];
|
|
168
|
+
tsBits[i] = Num2Bits(64); tsBits[i].in <== timestamp[i];
|
|
169
|
+
|
|
170
|
+
msg[i] = Poseidon(5);
|
|
171
|
+
msg[i].inputs[0] <== subjectKeyHi;
|
|
172
|
+
msg[i].inputs[1] <== subjectKeyLo;
|
|
173
|
+
msg[i].inputs[2] <== taskRef[i];
|
|
174
|
+
msg[i].inputs[3] <== status[i];
|
|
175
|
+
msg[i].inputs[4] <== timestamp[i];
|
|
176
|
+
|
|
177
|
+
sig[i] = EdDSAPoseidonVerifier();
|
|
178
|
+
sig[i].enabled <== present[i];
|
|
179
|
+
sig[i].Ax <== Ax;
|
|
180
|
+
sig[i].Ay <== Ay;
|
|
181
|
+
sig[i].S <== S[i];
|
|
182
|
+
sig[i].R8x <== R8x[i];
|
|
183
|
+
sig[i].R8y <== R8y[i];
|
|
184
|
+
sig[i].M <== msg[i].out;
|
|
185
|
+
|
|
186
|
+
// distinct records: strictly increasing taskRef over the filled prefix
|
|
187
|
+
if (i > 0) {
|
|
188
|
+
increasing[i] = LessThan(128);
|
|
189
|
+
increasing[i].in[0] <== taskRef[i - 1];
|
|
190
|
+
increasing[i].in[1] <== taskRef[i];
|
|
191
|
+
present[i] * (1 - increasing[i].out) === 0;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
isAccepted[i] = IsEqual();
|
|
195
|
+
isAccepted[i].in[0] <== status[i];
|
|
196
|
+
isAccepted[i].in[1] <== 1;
|
|
197
|
+
geT0[i] = LessEqThan(64);
|
|
198
|
+
geT0[i].in[0] <== t0;
|
|
199
|
+
geT0[i].in[1] <== timestamp[i];
|
|
200
|
+
leT1[i] = LessEqThan(64);
|
|
201
|
+
leT1[i].in[0] <== timestamp[i];
|
|
202
|
+
leT1[i].in[1] <== t1;
|
|
203
|
+
inWindow[i] <== geT0[i].out * leT1[i].out;
|
|
204
|
+
acceptedPresent[i] <== present[i] * isAccepted[i].out;
|
|
205
|
+
counted[i] <== acceptedPresent[i] * inWindow[i];
|
|
206
|
+
acc[i + 1] <== acc[i] + counted[i];
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// result = (count >= k)
|
|
210
|
+
component reach = GreaterEqThan(16);
|
|
211
|
+
reach.in[0] <== acc[n];
|
|
212
|
+
reach.in[1] <== k;
|
|
213
|
+
result <== reach.out;
|
|
214
|
+
|
|
215
|
+
// nullifier scoped to (schemeId, admissionDomain, epoch, challenge)
|
|
216
|
+
component nul = Poseidon(8);
|
|
217
|
+
nul.inputs[0] <== secret;
|
|
218
|
+
nul.inputs[1] <== schemeIdHi;
|
|
219
|
+
nul.inputs[2] <== schemeIdLo;
|
|
220
|
+
nul.inputs[3] <== admissionDomainHi;
|
|
221
|
+
nul.inputs[4] <== admissionDomainLo;
|
|
222
|
+
nul.inputs[5] <== epoch;
|
|
223
|
+
nul.inputs[6] <== challengeHi;
|
|
224
|
+
nul.inputs[7] <== challengeLo;
|
|
225
|
+
component nulSplit = Split128();
|
|
226
|
+
nulSplit.in <== nul.out;
|
|
227
|
+
nullifierHi <== nulSplit.hi;
|
|
228
|
+
nullifierLo <== nulSplit.lo;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
component main { public [subjectKeyHi, subjectKeyLo, challengeHi, challengeLo, t0, t1, k, sourceSetRootHi, sourceSetRootLo, schemeIdHi, schemeIdLo, epoch, admissionDomainHi, admissionDomainLo] } = KYAPredicateCountV1(8, 16);
|