Create Lambda handler with patent seam simulation#1
Conversation
Implements two patent concepts for spiralverse-protocol-test Lambda: - Manifold-gated dual-lane: Geometric classifier computing lane bit from context using spiral projection onto golden-ratio manifold - Trajectory + drift coherence: 5-variable kernel authorization (origin, velocity, curvature, phase, signature) Endpoints: - POST /brain-lane (fast path) - POST /oversight-lane (strict path with trajectory verification) - POST /verify (standalone trajectory check) - GET /health Zero dependencies, 169 lines, ready for AWS Lambda console.
There was a problem hiding this comment.
Pull request overview
This PR introduces a new AWS Lambda handler implementing two patent concepts: a manifold-gated dual-lane classifier using golden-ratio spiral projection and a trajectory coherence kernel for authorization. The handler provides four REST endpoints for processing requests through different validation paths.
Changes:
- Implements ManifoldClassifier for geometric request classification using entropy, complexity, and depth metrics
- Implements TrajectoryKernel for 5-variable authorization based on origin, velocity, curvature, phase, and signature
- Adds Lambda handler with four endpoints: /health, /brain-lane, /oversight-lane, and /verify
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| objectDepth(obj, d = 0) { | ||
| if (typeof obj !== 'object' || obj === null) return d; | ||
| return Math.max(...Object.values(obj).map(v => this.objectDepth(v, d + 1)), d); |
There was a problem hiding this comment.
The Math.max call with spread operator on an empty array will return -Infinity when the object has no own properties. This could cause unexpected behavior in subsequent calculations. Consider handling the empty object case explicitly by returning d when Object.values(obj) is empty.
| return Math.max(...Object.values(obj).map(v => this.objectDepth(v, d + 1)), d); | |
| const values = Object.values(obj); | |
| if (values.length === 0) return d; | |
| return Math.max(...values.map(v => this.objectDepth(v, d + 1)), d); |
| return respond(200, { status: 'healthy', seams: ['manifold-dual-lane', 'trajectory-kernel'], ts: Date.now() }); | ||
| } | ||
|
|
||
| const body = event.body ? JSON.parse(event.body) : {}; |
There was a problem hiding this comment.
JSON.parse is called without error handling. If the body contains invalid JSON, it will throw an error that will be caught by the outer try-catch with a generic error message. Consider adding more specific error handling for JSON parse failures to provide clearer feedback to API consumers about malformed request bodies.
| const body = event.body ? JSON.parse(event.body) : {}; | |
| let body = {}; | |
| if (event.body) { | |
| try { | |
| body = JSON.parse(event.body); | |
| } catch (parseErr) { | |
| return respond(400, { error: 'Invalid JSON body', message: parseErr.message }); | |
| } | |
| } |
| const diffs = [], diffs2 = []; | ||
| for (let i = 1; i < history.length; i++) diffs.push(history[i] - history[i-1]); | ||
| for (let i = 1; i < diffs.length; i++) diffs2.push(diffs[i] - diffs[i-1]); | ||
| const avgCurve = diffs2.reduce((a, b) => a + b, 0) / diffs2.length; |
There was a problem hiding this comment.
Division by zero will occur when diffs2.length is 0 (when history.length is less than 3 and the early return doesn't trigger, or when all first-order differences are identical). This results in NaN being returned instead of a meaningful value. Consider adding a check for empty diffs2 array before performing the division.
| const avgCurve = diffs2.reduce((a, b) => a + b, 0) / diffs2.length; | |
| const avgCurve = diffs2.length === 0 | |
| ? 0 | |
| : diffs2.reduce((a, b) => a + b, 0) / diffs2.length; |
|
|
||
| if (method === 'POST' && path === '/oversight-lane') { | ||
| const classification = ManifoldClassifier.classify({ payload: body, route: 'oversight' }); | ||
| const verification = TrajectoryKernel.verify({ payload: body, ...body }); |
There was a problem hiding this comment.
The spread operator ...body after payload: body creates redundant properties if body contains a 'payload' key. This could lead to unexpected behavior where body.payload is both nested under payload and potentially duplicated at the top level. Consider restructuring to avoid potential property conflicts or documenting the intended merge behavior.
| } | ||
|
|
||
| if (method === 'POST' && path === '/verify') { | ||
| const verification = TrajectoryKernel.verify({ payload: body, ...body }); |
There was a problem hiding this comment.
The spread operator ...body after payload: body creates redundant properties if body contains a 'payload' key. This could lead to unexpected behavior where body.payload is both nested under payload and potentially duplicated at the top level. Consider restructuring to avoid potential property conflicts or documenting the intended merge behavior.
|
|
||
| computeVelocity(reqTime, now) { | ||
| const delta = Math.max(1, now - reqTime); | ||
| return Math.min(1, 1000 / delta); |
There was a problem hiding this comment.
Magic number 1000 is used in velocity calculation without explanation. This represents the scaling factor for the velocity metric but its significance is undocumented. Consider defining this as a named constant like VELOCITY_SCALE_MS to clarify its purpose in the velocity calculation.
| return -Object.values(freq).reduce((h, f) => { | ||
| const p = f / len; | ||
| return h + p * Math.log2(p); | ||
| }, 0); |
There was a problem hiding this comment.
The Shannon entropy calculation will return NaN when given an empty string because the reduce will return 0 and negating it still gives 0, but more critically, when str.length is 0, the freq object will be empty and Object.values(freq) will be empty, resulting in the reduce returning 0. However, the function doesn't handle this edge case explicitly. Consider returning 0 for empty strings to make the behavior explicit.
| return Math.tanh(avgCurve / 100) * 0.5 + 0.5; | ||
| }, | ||
|
|
||
| computePhase(now) { return (now % 60000) / 60000; }, |
There was a problem hiding this comment.
Magic number 60000 (60 seconds in milliseconds) is used for phase calculation without explanation. Consider defining this as a named constant like PHASE_CYCLE_MS to improve code clarity and make it easier to adjust the phase cycle period.
| for (let i = 1; i < history.length; i++) diffs.push(history[i] - history[i-1]); | ||
| for (let i = 1; i < diffs.length; i++) diffs2.push(diffs[i] - diffs[i-1]); | ||
| const avgCurve = diffs2.reduce((a, b) => a + b, 0) / diffs2.length; | ||
| return Math.tanh(avgCurve / 100) * 0.5 + 0.5; |
There was a problem hiding this comment.
Magic number 100 is used to scale curvature without explanation. This scaling factor affects how trajectory curvature influences authorization decisions but its rationale is not documented. Consider defining this as a named constant like CURVATURE_SCALE to improve maintainability.
|
|
||
| computeSignature(request) { | ||
| const payload = JSON.stringify(request.payload || {}); | ||
| let sig = 0; |
There was a problem hiding this comment.
Magic numbers 31 and 0xFFFFFFFF are used in signature hash computation without explanation. While these are common hash function constants, documenting their purpose would improve code clarity. Consider adding a comment explaining this is a simple polynomial rolling hash implementation.
| let sig = 0; | |
| let sig = 0; | |
| // Simple polynomial rolling hash over the payload string: | |
| // - 31 is the polynomial base used to mix in each character code | |
| // - 0xFFFFFFFF constrains the result to a 32-bit unsigned integer domain |
Implements two patent concepts for spiralverse-protocol-test Lambda:
Endpoints:
Zero dependencies, 169 lines, ready for AWS Lambda console.