Factory docs, home
Page navigation

A record from the Factory repository, docs/service-access-receipt.json, shown as committed except that its local paths appear as placeholders in angle brackets, such as <local evidence archive>, standing for files that are not published. Every hash, date and count is as recorded. The build review says what the Factory's receipts support.

{
  "recordedAt": "2026-09-29T17:43:06+00:00",
  "base": "985b5f9",
  "branch": "factory/service-access",
  "disposition": "provisionally-accepted-astra-pending",
  "scope": "Service access, increment 1: a names-only catalogue of eleven Service kinds, deny-first tree scanning, listing and sign-in parsing, the Service map fold, exclusive store bindings, declarations, confirmations, route pins and readiness, on test-made fixtures only. No reader runs a process, no runbook, blocker, gate, executor profile or value-touching code exists, and nothing composes the module.",
  "describes": "src/service-kinds.ts, src/service-discovery.ts and src/service-access.ts as first recorded, and the service-access declaration in src/intelligence.ts",
  "specification": "<local evidence archive> section 12, increment 1 (design accepted by Astra round 5 PASS, astra-design-r5.md)",
  "ownerDirection": "One dedicated 1Password vault per Product (sf-<productId>), owner-created and bound by vault id, is the source of truth for its secrets (spec section 3, decision 2); increment 1 carries its onepassword-vault binding, the onepassword-ref location and per-kind item templates, and reads no vault.",
  "tests": {
    "files": {
      "test/service-kinds.test.ts": 4,
      "test/service-discovery.test.ts": 23,
      "test/service-access.test.ts": 23,
      "test/service-access-canaries.test.ts": 2,
      "test/service-access-boundaries.test.ts": 3,
      "test/service-access-adversarial.test.ts": 14,
      "test/service-access-regressions.test.ts": 14
    },
    "existingTestsChanged": "one assertion in test/service-discovery.test.ts tightened after Astra round 1: a path outside RelPath that no rule would touch now leaves the tree partial, as spec section 5 step 3 and acceptance 3 require (the test's title updated to match); the adversarial suite is unchanged",
    "adversarial": {
      "suite": "test/service-access-adversarial.test.ts",
      "tests": 14,
      "passingBeforeFixes": 0,
      "dispositions": "<local evidence archive>"
    }
  },
  "mutations": "Nine source mutations, each reversing one Astra round 1 fix (expression literals, Gradle strings, template shell quotes, environment override, newest listing time, future captures, quiet out-of-grammar paths, environment listing freshness, quoted forward flags), each failing the regression suite; sources restored byte for byte (<local evidence archive>).",
  "acceptance": "provisionally accepted — Fable 5.1 (max) round 1; Astra review pending (Codex usage limit until 2026-10-03 18:00). Owner decision 2026-09-29, \"Fable interim, Astra later\": Fable 5.1 at max effort verifies independently of the Opus builder until Astra (gpt-6-astra) can review; from 2026-10-03 18:00 Astra reviews this increment and the highest-numbered astra-r*.md report under the inc1 directory holds the verdict, superseding the Fable round.",
  "review": {
    "model": "gpt-6-astra (rounds 1-2); claude-fable-5-1 interim (Fable round 1)",
    "effort": "high (Astra); max (Fable)",
    "sandbox": "Astra: read-only; it cannot create temporary files, so it checked the archived host test logs. Fable: read-only on the worktree, probes on a disposable journal",
    "scope": "git diff 985b5f9 (the branch's base; main has since moved on with unrelated lifecycle work) plus untracked files",
    "rounds": [
      {
        "report": "<local evidence archive>",
        "verdict": "FAIL",
        "findings": "eight: Gradle and TOML string literals read as dependencies; an env-template quote opened inside an unquoted value; expression string literals read as references; an unread environment treated as having no override; fresh environment evidence hiding a stale repository listing; observations after asOf giving ready; a path outside RelPath leaving coverage complete; the receipt, build-review row and verified scope missing. All reproduced and fixed with their classes (dispositions.md).",
        "model": "gpt-6-astra",
        "effort": "high"
      },
      {
        "report": "<local evidence archive>",
        "verdict": "none",
        "findings": "no verdict: the run stopped at the Codex usage limit (available again 2026-10-03 18:00) before writing a report; no other reviewer substituted",
        "model": "gpt-6-astra",
        "effort": "high"
      },
      {
        "report": "<local evidence archive>",
        "model": "claude-fable-5-1",
        "effort": "max",
        "interim": true,
        "verdict": "PASS",
        "findings": "two: (1) the documentation denied the receipt and build-review row and carried the superseded acceptance label, corrected before merge in the documents this receipt hashes; (2) absence, referenced-not-stored and missing do not account for organisation-level secrets and variables on an organisation-owned repository, unreachable on this fixture-only increment and open until before increment 2. All eight Astra round 1 findings and the fourteen adversarial defects confirmed resolved."
      }
    ]
  },
  "verification": {
    "strictTypecheck": "passed",
    "focused": {
      "tests": 133,
      "pass": 133,
      "fail": 0,
      "cancelled": 0,
      "skipped": 0,
      "todo": 0
    },
    "focusedExit": 0,
    "focusedLog": "<local evidence archive>",
    "full": {
      "tests": 1019,
      "pass": 1019,
      "fail": 0,
      "cancelled": 0,
      "skipped": 0,
      "todo": 0
    },
    "checkExit": 0,
    "checkLog": "<local evidence archive>"
  },
  "limits": [
    "Test-made fixtures only: no live listing, sign-in, repository or vault is read (increments 2 and 4); the Tally-shaped fixture is synthetic",
    "The credential screen is a heuristic over shapes, not a secret scanner: a name-shaped secret cannot be told from a name, and a hostile repository can always write one as a name",
    "The workflow line grammar, the dotenv reading, the shell reading of scripts and the Kotlin and TOML lexers approximate libyaml, dotenv, bash and the compilers; what they cannot follow is partial or ends the reading, but a construct none anticipates may still be misread",
    "Readiness is presence, never validity; expiry is unknown until an owner statement (increment 3)",
    "An empty listing never proves absence, so a Product with no secrets stays unknown until an owner statement can say a store is empty (increment 3)",
    "Organisation-level secrets and variables are not listed (spec decision 6): in a repository an organisation owns, a name absent from the repository's and environment's listings may still resolve from the organisation, and absence, referenced-not-stored and missing do not yet account for that level (Fable round 1 finding 2: open, to be closed by a reviewed spec amendment and code before increment 2 reads any live repository)",
    "Bindings, declarations, confirmations and pins are attribution any process able to write the journal can forge",
    "Provisional: Fable 5.1 is an interim reviewer under the owner's decision; this acceptance is not an Astra PASS and stands only until Astra's review from 2026-10-03 18:00",
    "Based on main at 985b5f9; main has since moved on (lifecycle increments), and the merge, which touches the README intelligence block, src/intelligence.ts, the combined model and the site, is not covered by this receipt"
  ],
  "evidenceSha256": {
    "src/service-kinds.ts": "7a5a460502acf8fc2604b66fb7f2b4c9c4d774e43dea5870d9e361fe9c07806c",
    "src/service-discovery.ts": "8f5aa92ece772046f395900326b48649e2666faeda5aacca9ab51199063370b2",
    "src/service-access.ts": "fc06c35a56b49f56723fb26eff4b25dd4736c103752c65a8cb1c64e1c0d7639b",
    "src/intelligence.ts": "e5dfda55a577b7503f7db1a58520bd6982524f3e5af1c457ffc0ace723b88f21",
    "test/service-kinds.test.ts": "498920c90223c0a54423cf2c225221606cd3afd94e90bdf0637d19e747115128",
    "test/service-discovery.test.ts": "4cc1fd241c798047b122947647e927ae97d445cfae7fa5b509a05585178e7fe2",
    "test/service-access.test.ts": "a0b3e0495f483df8cc5d48599772e6ad6acf7359e9d5aa4c579f9bf5138c06f4",
    "test/service-access-canaries.test.ts": "19e1cb87b9cdd2459033a451693fc8abfea460df020a636783e696d09699b0df",
    "test/service-access-boundaries.test.ts": "754de78939d4a06cadf3f1f1ca39b5d05c471800a33a6fb3c414d67836499bf3",
    "test/service-access-adversarial.test.ts": "4bedfe77d18c133c81020f4951e36f47ad64632061f0b2712d702e8cb344414d",
    "test/service-access-regressions.test.ts": "5f478952412ab22c6bb4efcdfe288b402c321e314bb52adb488c5895989f4f1d",
    "test/helpers/service-access.ts": "2c0073271caa56c787c2a63b9bdf5329964a42b18998ab122c96791a64a63ed8",
    "test/helpers/service-access-child.ts": "dbd209dff3acfef8908b6264447d458bd86c1741766f615b3f87d214f551e2b0",
    "docs/agents/service-access.md": "3547a37d23791fbf9475e6a537595c7dc608ca2a5f29633d526dad588c6c4157",
    "docs/guide/service-access.md": "cc1c9a982ff22074587d454f4a660a5c84b415ac0a5136d4d9ebcd7ba9d6b2b1",
    "docs/agents/factory-model.md": "cb90e439cc1ceea7b8cdadd02bd7707c7bc5e4df783ca4bb72d12539acef528a",
    "docs/build-review.md": "0bbe7484182e5f894150b0d402f72f9ef99b7507d88d76a34a2e09273bed3b69",
    "docs/design.md": "699444b9f021b75d9987ab729a496f5c1ca7add35a5fe4d8b9b5d8c8bab5fbe2",
    "docs/guide/index.md": "353a0bbba40ee6096156c9b5c62c213f7522031ee17dbae2c5f97cf2d90eabcd",
    "README.md": "fce22fe6c83c8e2a8dc237d1331ec5d4a4e9b957cd9d2006d565aabaa8ef3d60"
  }
}

Source: docs/service-access-receipt.json