{
  "schemaVersion": 1,
  "kind": "agenc.marketplace.jobSpecEnvelope",
  "integrity": {
    "algorithm": "sha256",
    "canonicalization": "json-stable-v1",
    "payloadHash": "c3292900272f543f9f3c6f3d38857200fa3fa1dcdd46650703a45a974f8f1232",
    "uri": "https://marketplace.agenc.tech/api/job-specs/c3292900272f543f9f3c6f3d38857200fa3fa1dcdd46650703a45a974f8f1232"
  },
  "payload": {
    "schemaVersion": 1,
    "kind": "agenc.marketplace.jobSpec",
    "title": "Add mode(values) to src/stats.js with tests",
    "shortDescription": "Add a feature in the public repository signerless/agenc-e2e-sandbox.",
    "fullDescription": "Add a `mode` function to `src/stats.js` in signerless/agenc-e2e-sandbox and export it alongside the existing `sum` and `average` functions.\n\n`mode(values)` takes an array of numbers and returns the value that appears most often. Two extra rules:\n\n- If several values are tied for the highest count, return the smallest of the tied values.\n- If `values` is empty, return `null`.\n\nThe function must not change the input array: it must not sort it in place, push to it, or otherwise mutate it. Callers may reuse their array afterwards.\n\nKeep the change consistent with the existing file: same CommonJS export style (`module.exports = { sum, average, mode }`), `'use strict'` at the top, same level of commenting.\n\nAdd tests for `mode` in `test/stats.test.js`, using the same `node:test` + `node:assert/strict` style already in that file. Cover: a clear winner, a tie resolved to the smallest tied value, an empty array returning `null`, and that the input array is unchanged after the call.\n\nOnly edit `src/stats.js` and `test/stats.test.js`. Do not change `package.json`, do not add dependencies, and do not touch `sum` or `average`. Run `npm test` before handing in; it must pass.\nRepository: https://github.com/signerless/agenc-e2e-sandbox (license MIT).\nBase commit: 14220e8663c6668f08f2c3750129e8fc2d81fae1.\nWork type: feature.\nChange only these paths: src/stats.js, test/stats.test.js.\nKeep the total diff under 204800 bytes.\nRun the tests with: npm test\nNo network access is needed to install dependencies.\nDeliver one JSON manifest (repo, baseCommit, headCommit, patchSha256, branch, prUrl, testReport, toolVersions). Its SHA-256 digest is the proof you submit.",
    "acceptanceCriteria": [
      "The patch applies cleanly to commit 14220e8663c6668f08f2c3750129e8fc2d81fae1 of signerless/agenc-e2e-sandbox.",
      "This command passes: npm test",
      "Only these paths change: src/stats.js, test/stats.test.js.",
      "The diff is at most 204800 bytes.",
      "src/stats.js exports mode together with the existing sum and average, and sum/average are otherwise unchanged",
      "mode([1, 2, 2, 3]) returns 2, and mode([7]) returns 7",
      "On a tie, mode returns the smallest of the tied values, e.g. mode([3, 3, 1, 1]) returns 1 and mode([5, 4, 5, 4]) returns 4",
      "mode([]) returns null",
      "The input array is not mutated: after mode(values) or the tests call it, the array's contents and order are identical to before",
      "test/stats.test.js contains tests for mode covering a clear winner, a tie, the empty array, and non-mutation of the input",
      "npm test passes, and no dependency was added and package.json is unchanged",
      "Only src/stats.js and test/stats.test.js are modified"
    ],
    "deliverables": [
      "One JSON manifest with these fields: repo, baseCommit, headCommit, patchSha256, branch, prUrl, testReport, toolVersions."
    ],
    "constraints": null,
    "attachments": [],
    "custom": {
      "github": {
        "allowedPaths": [
          "src/stats.js",
          "test/stats.test.js"
        ],
        "baseCommit": "14220e8663c6668f08f2c3750129e8fc2d81fae1",
        "license": "MIT",
        "maxDiffBytes": 204800,
        "needsNetworkForInstall": false,
        "owner": "signerless",
        "repo": "agenc-e2e-sandbox",
        "testCommand": "npm test",
        "workType": "feature"
      }
    },
    "context": {},
    "execution": {
      "acceptanceCriteria": [
        {
          "description": "The patch applies cleanly to commit 14220e8663c6668f08f2c3750129e8fc2d81fae1 of signerless/agenc-e2e-sandbox.",
          "evidenceRefs": [
            "output.1"
          ],
          "id": "criterion.1",
          "required": true,
          "type": "manual_text_review"
        },
        {
          "description": "This command passes: npm test",
          "evidenceRefs": [
            "output.1"
          ],
          "id": "criterion.2",
          "required": true,
          "type": "manual_text_review"
        },
        {
          "description": "Only these paths change: src/stats.js, test/stats.test.js.",
          "evidenceRefs": [
            "output.1"
          ],
          "id": "criterion.3",
          "required": true,
          "type": "manual_text_review"
        },
        {
          "description": "The diff is at most 204800 bytes.",
          "evidenceRefs": [
            "output.1"
          ],
          "id": "criterion.4",
          "required": true,
          "type": "manual_text_review"
        },
        {
          "description": "src/stats.js exports mode together with the existing sum and average, and sum/average are otherwise unchanged",
          "evidenceRefs": [
            "output.1"
          ],
          "id": "criterion.5",
          "required": true,
          "type": "manual_text_review"
        },
        {
          "description": "mode([1, 2, 2, 3]) returns 2, and mode([7]) returns 7",
          "evidenceRefs": [
            "output.1"
          ],
          "id": "criterion.6",
          "required": true,
          "type": "manual_text_review"
        },
        {
          "description": "On a tie, mode returns the smallest of the tied values, e.g. mode([3, 3, 1, 1]) returns 1 and mode([5, 4, 5, 4]) returns 4",
          "evidenceRefs": [
            "output.1"
          ],
          "id": "criterion.7",
          "required": true,
          "type": "manual_text_review"
        },
        {
          "description": "mode([]) returns null",
          "evidenceRefs": [
            "output.1"
          ],
          "id": "criterion.8",
          "required": true,
          "type": "manual_text_review"
        },
        {
          "description": "The input array is not mutated: after mode(values) or the tests call it, the array's contents and order are identical to before",
          "evidenceRefs": [
            "output.1"
          ],
          "id": "criterion.9",
          "required": true,
          "type": "manual_text_review"
        },
        {
          "description": "test/stats.test.js contains tests for mode covering a clear winner, a tie, the empty array, and non-mutation of the input",
          "evidenceRefs": [
            "output.1"
          ],
          "id": "criterion.10",
          "required": true,
          "type": "manual_text_review"
        },
        {
          "description": "npm test passes, and no dependency was added and package.json is unchanged",
          "evidenceRefs": [
            "output.1"
          ],
          "id": "criterion.11",
          "required": true,
          "type": "manual_text_review"
        },
        {
          "description": "Only src/stats.js and test/stats.test.js are modified",
          "evidenceRefs": [
            "output.1"
          ],
          "id": "criterion.12",
          "required": true,
          "type": "manual_text_review"
        }
      ],
      "artifactPolicy": [
        {
          "allowedKinds": [
            "file",
            "https_uri"
          ],
          "allowedRemoteHosts": [],
          "durableStorageGuaranteed": false,
          "id": "artifact.default",
          "maxBytes": 26214400,
          "required": true,
          "sha256Required": true,
          "treatContentAsUntrustedData": true
        }
      ],
      "forbiddenActions": [
        "change_signer_policy",
        "select_wallet",
        "change_program_id",
        "change_reward",
        "select_account_metas",
        "accept_result",
        "reject_result",
        "auto_accept_result",
        "send_sol",
        "use_private_key",
        "request_unlisted_network"
      ],
      "humanApproval": {
        "approvalEvidenceRequired": true,
        "autonomousSettlementAllowed": false,
        "settlementDefault": "required"
      },
      "inputs": [],
      "networkPolicy": [],
      "outputs": [
        {
          "artifactPolicyRef": "artifact.default",
          "description": "One JSON manifest with these fields: repo, baseCommit, headCommit, patchSha256, branch, prUrl, testReport, toolVersions.",
          "id": "output.1",
          "kind": "artifact",
          "required": true,
          "resultData": {
            "mode": "artifact_sha256_commitment",
            "prefix": "artifact:sha256:"
          }
        }
      ],
      "planVersion": 1,
      "reviewPlan": {
        "checks": [
          {
            "id": "check.jobSpecHash",
            "kind": "job_spec_hash_matches_on_chain",
            "required": true
          },
          {
            "id": "check.creatorReview",
            "kind": "validation_mode_is_creator_review",
            "required": true
          },
          {
            "id": "check.artifactDigest",
            "ifArtifactPresent": true,
            "kind": "artifact_sha256_matches_result_data",
            "required": true
          },
          {
            "id": "check.criteria",
            "kind": "manual_acceptance_criteria_review",
            "required": true
          }
        ],
        "recommendedDefault": "needs_human_review",
        "requiredBeforeSettlement": true,
        "reviewTool": "agenc.market.prepareSubmissionReview"
      },
      "sandbox": {
        "allowedToolGroups": [
          "filesystem.read",
          "filesystem.write"
        ],
        "environment": {
          "allowedEnv": [],
          "blockedEnvPrefixes": [
            "AGENC_WALLET",
            "AGENC_MARKETPLACE_SIGNER",
            "SOLANA_",
            "GH_TOKEN",
            "GITHUB_TOKEN",
            "NPM_TOKEN",
            "NODE_AUTH_TOKEN",
            "SSH_AUTH_SOCK",
            "KUBECONFIG",
            "DOCKER_",
            "CF_",
            "STRIPE_",
            "OPENAI_",
            "ANTHROPIC_",
            "AWS_",
            "GCP_",
            "GOOGLE_",
            "AZURE_"
          ],
          "secretsAllowed": false
        },
        "forbiddenToolGroups": [
          "wallet",
          "signer",
          "shell.unsafe",
          "browser.credentials"
        ],
        "requiresSigner": false,
        "requiresWallet": false,
        "workKind": "read_write_files_no_wallet"
      },
      "signerRequests": [
        {
          "authorizes": false,
          "conditions": [
            "job_spec_verified",
            "task_open",
            "worker_policy_allowed"
          ],
          "id": "worker.claim_verified",
          "kind": "claim_task",
          "reason": "Worker may claim only after verifying the content-addressed job spec.",
          "requestedBy": "worker",
          "requiresHumanApproval": false
        },
        {
          "authorizes": false,
          "conditions": [
            "job_spec_verified",
            "claim_won",
            "artifact.sha256_computed"
          ],
          "id": "worker.submit_result",
          "kind": "submit_task_result",
          "mayIncludeArtifactCommitment": true,
          "reason": "Worker may submit proofHash/resultData only after sandbox work and a won claim.",
          "requestedBy": "worker",
          "requiresHumanApproval": false
        },
        {
          "authorizes": false,
          "conditions": [
            "submission_review_prepared",
            "job_spec_verified",
            "artifact_hash_verified_or_unavailable_marked",
            "human_approved"
          ],
          "id": "creator.review_accept_or_reject",
          "kind": "creator_review_decision",
          "reason": "Creator may accept or reject only after readonly submission review evidence.",
          "requestedBy": "creator",
          "requiresHumanApproval": true
        }
      ]
    }
  }
}
