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"
}
}
