{"_id":"feature-factory","_rev":"30-ea2e2c8167da075c85110e45ecbe7760","name":"feature-factory","dist-tags":{"latest":"0.10.10"},"versions":{"0.7.0":{"name":"feature-factory","version":"0.7.0","license":"MIT","_id":"feature-factory@0.7.0","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"1dbb574ff6d4ad56cbfa54f31372ea08a50aded6","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.7.0.tgz","fileCount":33,"integrity":"sha512-NGIIzIqXHNv5WdX5k2eqhnCZ3/JKonsPBXTm4zs2kMhOWfIg6j0icxSjoXp3fIdGYAFKS3qvdjq4gx5cdrIoYQ==","signatures":[{"sig":"MEQCIGoFIoLx7b+BVZTiHUz7xUy+CSIBROsiS/eFW3b8GqP7AiBtk1MqVqbUxsE1jpZlwpYQq0TxvXVa1IkNN1Jz0zfJ/w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":478163},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"0ab2daf1bfa01ea44fa857af96ca2da6e1e553b5","scripts":{"test":"node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"jcarreira","email":"jcarreira@gmail.com"},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.6.2","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.11.1","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.7.0_1786894332332_0.38898996141760733","host":"s3://npm-registry-packages-npm-production"}},"0.7.1":{"name":"feature-factory","version":"0.7.1","license":"MIT","_id":"feature-factory@0.7.1","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"91076724dc25322b2d8bee4fdcd0b503feb678de","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.7.1.tgz","fileCount":33,"integrity":"sha512-1abRw4pq7qbVNuDmIoRkuzvHNyIwVSI1SBrGuw1UEA3FddPMmjO8jLUjDTtBuFzIEqU3Ns6iQb+jyNT1e7bAbQ==","signatures":[{"sig":"MEYCIQDRKX2PuHgu5fFNS6w9EbjI+dI9ejBLctz5Y5+JBABpiAIhALh939g26tTyJRDRjZGRdyTyHttoEbR8EAHpYMCGVMsP","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.7.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":479746},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"7399d7af6c902343fdcd21b9916625ea701625c4","scripts":{"test":"node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.17.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.19.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.7.1_1787227299724_0.30422081899217424","host":"s3://npm-registry-packages-npm-production"}},"0.7.2":{"name":"feature-factory","version":"0.7.2","license":"MIT","_id":"feature-factory@0.7.2","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"e01caa51e03ffb30d10def9f2d619e0deb3319d8","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.7.2.tgz","fileCount":33,"integrity":"sha512-UubgjJ1JSOPm6gEJYvRBhVp1YaWkoxyKN/V7SGVbZB2S18w5rTzFK6yE60FFGhjQzczFbvcM4zUV+pPgfh5w4Q==","signatures":[{"sig":"MEQCIHJVZlbPh5cUFavD5uMwKvcn3U3iCLB58zRIxGvEJGpGAiBD5LNhegvwWbxdyYKKVhqDcBQIFNwLp38IMuP06l8PpA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.7.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":481480},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"91679c1c503ddb0c43c1b67eada4bcdb171119fc","scripts":{"test":"node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.17.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.19.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.7.2_1787273494016_0.2565039818111885","host":"s3://npm-registry-packages-npm-production"}},"0.7.3":{"name":"feature-factory","version":"0.7.3","license":"MIT","_id":"feature-factory@0.7.3","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"3667cb541d0ee6e6c402b521077b991e61cd5b53","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.7.3.tgz","fileCount":33,"integrity":"sha512-mTIfpJMk13h46THL0Eq0D1gm9g7Rj3n3UGzlZrK4CHm7XIPh4drCihC2AJlObsKqRJwQyNCo9UHBAkFDCSqHAw==","signatures":[{"sig":"MEUCIQDA7AJcBhBtXd6S2OtvQNKUgUdVGpxDutZngshEQoJSdQIgJer3J8ZVGKSfFusZFaCbkMYmpK4L9fMj/CTVpSBFSQk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.7.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":484119},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"b80c54c479b14b83fd56ceb7558adeff667301ba","scripts":{"test":"node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.17.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.19.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.7.3_1787694266775_0.3331450096940667","host":"s3://npm-registry-packages-npm-production"}},"0.7.4":{"name":"feature-factory","version":"0.7.4","license":"MIT","_id":"feature-factory@0.7.4","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"602039e62fb3af00a83e1703d6a5ea5cc320bf70","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.7.4.tgz","fileCount":33,"integrity":"sha512-jRx7bgiS9yVHIbObKMOEUqt4uv9klYHMFGH2mOx4X6DQFtSw80IYhCfJPzOKDPY7FuIcmknc8DE8jdoE0nik6A==","signatures":[{"sig":"MEQCIA8f+zTBlHbuEwKT6B0QLTxTF1X5C+JVFC4+gLfJa73mAiA86Pdhe6IE3BUVC8QLu1Co1sVzvxc50e9nUGXXWRqsMA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.7.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":484979},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"bc999c85c314dabf67886a87837a5cd29a9f7228","scripts":{"test":"node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.17.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.19.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.7.4_1787835760572_0.17274037903260897","host":"s3://npm-registry-packages-npm-production"}},"0.7.5":{"name":"feature-factory","version":"0.7.5","license":"MIT","_id":"feature-factory@0.7.5","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"dbb70a204bf1c3456d76704a99d3cb761ac7b6a1","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.7.5.tgz","fileCount":33,"integrity":"sha512-R7rMiipyoxcd5dbUq9O3psgbxnbAk03Q8LvAtHhXq3sHPmm0FVT2igTMLOnlZZ5wOeSYp2YCVBWHtvwkil92Iw==","signatures":[{"sig":"MEUCIF5YQnUexKUY2hD4nPrCZgmq2UEkNQ0UgwnaLAaci/EYAiEA9+6l2xQ1Fxb0q2Ms9Os5i2ikVDUsyCANdhSwZJBp5kg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.7.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":486891},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"47c9793396ffab54a06099252eb93373acf736ed","scripts":{"test":"node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.17.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.19.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.7.5_1787856762595_0.1008643570282286","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"feature-factory","version":"0.8.0","license":"MIT","_id":"feature-factory@0.8.0","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"01b2bf4aea01a98b9cb5f0f32d58fcee296690b1","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.8.0.tgz","fileCount":33,"integrity":"sha512-GOItFoUj7MjcHwOL+5ps6lLyNCnCd9w0NVMs0fwzzy2GwtRXpF9WbNAajTTjtAavUOGODuHVw+/Xu3dbfUZVOg==","signatures":[{"sig":"MEQCIGpbouKtMWpqZl589C62YYtADnyReMyfhAFdgWJg6af2AiApEq+KqH82UL+2UpcfZh2Q6MdDFWTYiqlU4qBa7mHCoA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.8.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":490246},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"c3e0de95533a12a01043b853cdc99f3d0fa81bd6","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.17.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.19.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.8.0_1787883755538_0.16266631901494533","host":"s3://npm-registry-packages-npm-production"}},"0.8.1":{"name":"feature-factory","version":"0.8.1","license":"MIT","_id":"feature-factory@0.8.1","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"339fc0f2b19c5ecae4f70486cfb0cec2e46f2935","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.8.1.tgz","fileCount":33,"integrity":"sha512-uuSo8ETXtZPbqLSESAO00JgnKUsSt844NsOYwF18qQ7i3jAdxOs/wa/u4JevIUrqlyJFPKO18scNput/27giDg==","signatures":[{"sig":"MEQCIG+3tQVQgXSgcHeqiarvbDtbywf8TBLVJnalRs/PLJyMAiBZq7ObCRonPFOO1Bplfr132fpAF6+F1JARUbAFK47ZTw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.8.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":490246},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"db2a2d334d41c60eb134eb39f01ea3782f444b7e","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.19.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.20.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.8.1_1788444666817_0.2824435612721934","host":"s3://npm-registry-packages-npm-production"}},"0.8.2":{"name":"feature-factory","version":"0.8.2","license":"MIT","_id":"feature-factory@0.8.2","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"67d6a9e95660031e9f7143db60cf0c17a9160e8e","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.8.2.tgz","fileCount":33,"integrity":"sha512-eP85H5ssMFBcr8Rlbikt2bJXt2xxRMJ6JeKz1mA6a/XXyOVOZcuuo1JqcoJ202AtYCWDkjwN8cgmKMgwhm8V0A==","signatures":[{"sig":"MEUCIH6A/AIzuZVHSWcHtqerjJvzMbdthG0qcqvVZKKs+dwbAiEA3m4rrrfcriwrbdORlzIOUlKZu0qdZ6NOIbNR05HHDxk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.8.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":495449},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"1b5f28543c22970c9d4b01d829fc4bbde36b8a3f","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.17.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.19.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.8.2_1788486122799_0.9387106081408663","host":"s3://npm-registry-packages-npm-production"}},"0.8.3":{"name":"feature-factory","version":"0.8.3","license":"MIT","_id":"feature-factory@0.8.3","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"e1ca4048a20e9e9759499274ae54819d60b86f66","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.8.3.tgz","fileCount":33,"integrity":"sha512-voU35+JuLC5eO/m7J8WvVnu59gqpekNbS6H0vp0KafPKVR720plFwvLeHScahfWvhw62tgovODXBzJxZDthmLQ==","signatures":[{"sig":"MEQCICTdunrzNm1i5hQjUti7XLB3F+ebFAZcjfXlVgzajAqHAiAkx39rvIltdM/irVrI/snwMCNeQWLv6evTHNVWfP4LoQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.8.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":500003},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"a27d0703b97becdb6e9c4fcdef31ce809a6a0cbc","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.19.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.20.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.8.3_1788569955366_0.6993931036683638","host":"s3://npm-registry-packages-npm-production"}},"0.8.4":{"name":"feature-factory","version":"0.8.4","license":"MIT","_id":"feature-factory@0.8.4","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"d7bbfc04a8156a523438c5ecc5145e8d7b7f8ee9","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.8.4.tgz","fileCount":33,"integrity":"sha512-RpvaDzTMTKJGapQElvBG4i9UM0sb99oKVP1fHK2k4e125RF/0nky1eIAIB/EZI4C6wnKHte7J0z22Tf2x4QL3g==","signatures":[{"sig":"MEQCIGaxgxqxrq9kNROBp/RT3mpBYI7kjdF7q4ViFA3n2uJAAiA2MHHBjSAtvYkuU7LxnpiH4w6Kb0SREBSPOjf80KM9MQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.8.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":501043},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"597b1202558a473d12334efd0666a76a564c6b6b","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.19.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.20.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.8.4_1789081956211_0.9767639479556238","host":"s3://npm-registry-packages-npm-production"}},"0.8.5":{"name":"feature-factory","version":"0.8.5","license":"MIT","_id":"feature-factory@0.8.5","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"f460224e1d0679180a60da63dd5a412e9766a507","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.8.5.tgz","fileCount":33,"integrity":"sha512-fnT9zbEBH6vdbCNer2zuqfWH183TFOvNz8a+Ph3LekhMF2TtP927SWdWbJCQyYHyTNCGkqrhTWq0dPL/ts8Dlw==","signatures":[{"sig":"MEQCIAyA71T9/mmoI7l4pzj//AgBAYcAbsEMycs14Vt5c9OSAiAOuaPH57PYgV0EsE1Myq41Tzn0fK/RoIPw/7xa/M0pDA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.8.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":502594},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"df246f196fc295e824d3e7dba60225323ea7cfb5","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.19.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.20.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.8.5_1789092442533_0.8601358147175542","host":"s3://npm-registry-packages-npm-production"}},"0.8.6":{"name":"feature-factory","version":"0.8.6","license":"MIT","_id":"feature-factory@0.8.6","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"63e22b54d7e91f09887e0f6808cf9de999d48295","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.8.6.tgz","fileCount":33,"integrity":"sha512-4XsUiKXkFCvOHwePkMF3genc/Qo/Zkoy8f8dB4uJ/vh+VlFlAP4z63yCit62I4X7dUjI9qJXLmt+RkevAJlySg==","signatures":[{"sig":"MEYCIQDx8PbciT4pL6oglDa2u8lKkM4x1cFRyrEZlRCgthuvDgIhAKEGF3B9819d+f9aWC4uwItOuGOlA27MA29MQWacuGmn","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.8.6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":503473},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"5f6de3ac0e8328663a0fe8afaa3a291236859f02","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.19.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.20.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.8.6_1789102054760_0.4999995119787699","host":"s3://npm-registry-packages-npm-production"}},"0.8.7":{"name":"feature-factory","version":"0.8.7","license":"MIT","_id":"feature-factory@0.8.7","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"9d7a5c4fb95876c3857a3dce76c2c542e175f47f","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.8.7.tgz","fileCount":33,"integrity":"sha512-prir5DGvD4lFajgan74wIv8HCtsTU1Tk6J0akZ4CKfK4hGcghONZG9sG1H6NohtsmaH6zzxU24uWBwBJ3F1lPA==","signatures":[{"sig":"MEQCIALU8M3fj9xpCfpng5wbCWg0s8LUecnZy68SOaQNSeRCAiA4iWkAmVoaL+RZT5IIXSgeKYfM8G7bYYDCY0HkJs00Yw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.8.7","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":504936},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"0ea43d9e96fb1cf8a345ed5f4b1ccfedca50a7cf","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.19.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.20.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.8.7_1789177639213_0.9149282251112603","host":"s3://npm-registry-packages-npm-production"}},"0.8.8":{"name":"feature-factory","version":"0.8.8","license":"MIT","_id":"feature-factory@0.8.8","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"6c7d5f8301d4b5e554a547f767738dd219005008","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.8.8.tgz","fileCount":33,"integrity":"sha512-ulBp78zD1SbSWMwxYAkKIeTooi3tgoPEmh32wpAHjcNM8cBN/5/nOgmKAH5dBnh4KhGQxPbhI7Q8/U86qlT4XA==","signatures":[{"sig":"MEUCIQCsPIOluL4nZ/WiVumsSNJZkLkcoCyyO8UCxdw0Nh26SgIgPWZcoeqrkEz3dePWveomKayXjzJUtu9TF1EPUu892VA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQDaIJGYDbxpnu1R6QhzB5MhrT07czR9GHlFa1G5+MoBagIgSzXOYKSpLiN4SzjCToUOrRaiZgVsSWuJDbZ6ZPPtUdY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.8.8","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":507741},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"657a1f1a16cb5a43266732abfe01ef58181140c8","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.19.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.20.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.8.8_1789583207715_0.10423403916600882","host":"s3://npm-registry-packages-npm-production"}},"0.8.9":{"name":"feature-factory","version":"0.8.9","license":"MIT","_id":"feature-factory@0.8.9","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"f60f474cc89c65469f02097b76975182653ce711","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.8.9.tgz","fileCount":33,"integrity":"sha512-QiJCVLdqsCEvor/RLIETVEtHkU4KB+BKDJVbGD7p/IzI4qu8F0Jf9loO0N8VdrUn7Ybw29K6Lwa1fUGOuUW6Ng==","signatures":[{"sig":"MEYCIQDkGPc6OGKeNB6AE3tDkq3kVHPpvyqj9q7Wnkh195QZuwIhAKVAy3wNfm02QS+ExiWaIclSgrj0V8VyKxyFyapsJDf+","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIDwSAgf9W87GaeQIFUHHbTxee8PdSSX0+B7Dds+B+E+FAiEA/dejOJCTXcZClktUOlhschew2WJUGNqo4u0xEmyJWGw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.8.9","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":520851},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"65070af9bb5a719cc74d9e4114974453c21d0f3b","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.19.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.20.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.8.9_1789610009377_0.39551138350824266","host":"s3://npm-registry-packages-npm-production"}},"0.9.0":{"name":"feature-factory","version":"0.9.0","license":"MIT","_id":"feature-factory@0.9.0","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"5ab573af50aca28af64cae5dab5885759eb6ed57","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.9.0.tgz","fileCount":33,"integrity":"sha512-8ZZSayEMMwvGDzUzbNUTEXxO9GzCrfq28O0tN1lpGmmG6T+4P5bKA8hY9+ujyyPIGlY5SSmhzV5IIbL6+2uc0g==","signatures":[{"sig":"MEQCIGDlhEwa0M4fG6VkFvP4+wtmwy4aYMncW+U5s0TLb9ztAiA6NU90RspE+dCgsxk2K1TiMAaWhRHs9Cm+yhtZ8LjTew==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQCE7PfedpYcntuNJLfLJuU4HwEY/RVOFdMc0gYajh7UOgIgUmDtyoE4sbP7AiJYuKHJClbl2CcuxifgsPGfEiEB+R8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.9.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":529557},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"776f5adaca49350742715342998435709cc5943f","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.19.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.20.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.9.0_1789680339145_0.9940608434786609","host":"s3://npm-registry-packages-npm-production"}},"0.9.1":{"name":"feature-factory","version":"0.9.1","license":"MIT","_id":"feature-factory@0.9.1","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"1e70907c2fdbcd2a7bbbd9f5f9bf1dea35f0004b","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.9.1.tgz","fileCount":33,"integrity":"sha512-ro0Wf/0ArjgSuZ+z+VL1vwcuqtRgJF5vGFq7rxjJixJ58/piHahlnFZRivn4CxK1G8VIQHpnWImlVox3szCf4Q==","signatures":[{"sig":"MEUCIAae/23izT5e/KdoaN/apdBtduBgEF6ZQEnpeeQTyZzhAiEA7PoWZevxWDMObNPW5uzw3IPbv3fDERo1B6nNbXAtyuU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQCJJQ09uoFoovvuEj2rMK/ONd9rKxtF/pe+Pvmu0433ogIgDb8vLMrtRnP4f5LyHZDa62s5FlMSolPQN/de6+KTVlU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.9.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":532046},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"6fa0f6696ebca17b170efb08deaabc4b13509d0e","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.19.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.20.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.9.1_1789777144550_0.7698011712031037","host":"s3://npm-registry-packages-npm-production"}},"0.9.2":{"name":"feature-factory","version":"0.9.2","license":"MIT","_id":"feature-factory@0.9.2","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"71f17741d5b66256855914ef994551a83b007e54","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.9.2.tgz","fileCount":33,"integrity":"sha512-zjI+rnARnwk/llA5E+ECCUpsJygUteINeBbhEt9jAE9xMu/r3G4fLcWMqznZUySEBePvzzSNgh8MBNcA2aT5xQ==","signatures":[{"sig":"MEUCIQD9fLgy467d59DriQL+ek451z2s0lGSb2BTCLXO24WqtAIgRqw3ZaUUriuN0W32TKxOFDZr7fWwe4M4BovaZ5Nrdvo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQC2+lF1SdzjCbzYVjICGE8DaU/r6zNWYsk3hUu+IbDAZQIhAIBLP0mMeyjJY0Kv37QgZQ7WgRmkSiXx/qLhR41B2JSN","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.9.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":533946},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"c5dea715c8a1f33b8c240f4e43da0034d8fad882","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.19.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.20.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.9.2_1789827241279_0.8647834860918275","host":"s3://npm-registry-packages-npm-production"}},"0.10.0":{"name":"feature-factory","version":"0.10.0","license":"MIT","_id":"feature-factory@0.10.0","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"3f68022c85aef93ad6c82e09dc13d02791c90ed8","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.10.0.tgz","fileCount":34,"integrity":"sha512-NBOYITarkNqJ+uSy8HdE1iYgSH9eJUOqLZgHKZfuLTOAVfaaf/BboAUtpYc//kqAsqHPLwLOIhxnSvdRAW9agw==","signatures":[{"sig":"MEYCIQDt1pC1e5Xr4LjYdcGfmwoj1RqfLHqEJwse9IXxKuSKcgIhAKHKWN8CUNdxBRawwqTLJEhnfgMkIFfe9+zSmZT+1dOA","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIEEQyufQ+lQ2vOqas7ZUy2bsahcHtEaRoJDEdjHjjsx7AiEAvE5aLxioPz8nNYdyQv26Fu2YV4E3nktXQ9jR/sc9ix4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.10.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":583314},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"76aba355b668b3457485085ed08968b03e05e410","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.19.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.20.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.10.0_1790045898620_0.7205287300973142","host":"s3://npm-registry-packages-npm-production"}},"0.10.1":{"name":"feature-factory","version":"0.10.1","license":"MIT","_id":"feature-factory@0.10.1","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"dc16e082d847ce6f3113f30c75425a18b4aafc44","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.10.1.tgz","fileCount":35,"integrity":"sha512-SVsi3c3YHq29lWgDk0y6HKcRFY1yY0CruUMfrxCXD90oZDrEJ3XIWjOmdgxebmYrvyaY/8ni69HPR1zg3klBMQ==","signatures":[{"sig":"MEYCIQDCURP9aDA6J0HmCuo9aAD8RaU2f7Ebpk6FK8jAPG5UUAIhAIzfLk3LTgo4TQdd6UmFYsajptFpP7b69sTYKdkUlE0O","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQDzT2Xob2TbZJSTdV6wTjnI3Bu1HMXYS0udjyewNQQILAIhAIjm09DkdJoRBdb7i+ONy54t8cdHhs/Ti1KDNE1mg9HK","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.10.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":628666},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"d1bcf63c94529180db03670ddcd67cd01a58add2","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.19.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.21.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.10.1_1790103733896_0.23107396799215607","host":"s3://npm-registry-packages-npm-production"}},"0.10.2":{"name":"feature-factory","version":"0.10.2","license":"MIT","_id":"feature-factory@0.10.2","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"589b74ce762c62bc5a9d7f4ed032a68a34f25e40","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.10.2.tgz","fileCount":36,"integrity":"sha512-N7GSfbfJWpyxOPQRae2eNsqYPBsXZNPewQTqyxBQ/MMGxrc2xNamCejDAS0EMzY3IDvduWQ1yZMAb4aAiqeeNw==","signatures":[{"sig":"MEQCICJ/AC9Tb0P3oYsIxnGDbsEKlOnjR2WCXkypCI5cj8duAiBW0Ey4x3dwmQIutrRdGuW93FYUordlsE9MgjWQx9V4zA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCICRuGW1emYO8ciHo/m9Wm5E4H0608p6VdIhULRgtmvH2AiBuoNBoNgCfVqi7TLn+rZTGLdaH6f8WtPSv3gKxLz6J2Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.10.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":648994},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"c8e35d725b93abe67823f1cb417cc5ad4369d55f","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.19.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.20.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.10.2_1790125597121_0.022452047536392072","host":"s3://npm-registry-packages-npm-production"}},"0.10.3":{"name":"feature-factory","version":"0.10.3","license":"MIT","_id":"feature-factory@0.10.3","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"0ef53fc35872b753ed64094dd416493c10704dc0","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.10.3.tgz","fileCount":36,"integrity":"sha512-rxQ5rNwSG7pFF8E6WRGF9bw9wo4hsffpaDBkqXDdyd/a5EUM48B4DrQV5X1+KioFNZL8odYet1wIf6gnSO3g3w==","signatures":[{"sig":"MEQCID9MMfGkaoRoqy54OUtsBSSloAioZ6aNc6AKjHsCLA6sAiAXqUJW4UJHM3LZyiqK7BzUokcetameYgfoHFVN8NWF7w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQDG89de4lkJcxA6yjfR+otjbnwAdoXHElN/mGenBx3WjwIgQ05J0nLwosBcaJL54FA0u/fLeEG0iQzpIrMjqBDfFkI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.10.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":649693},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"fb300791666fa178e0fdc1ee323a2a2048aa2210","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.19.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.20.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.10.3_1790167252437_0.3346821175691823","host":"s3://npm-registry-packages-npm-production"}},"0.10.4":{"name":"feature-factory","version":"0.10.4","license":"MIT","_id":"feature-factory@0.10.4","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"6f66a11234403c59cb5c99d9f486f045ebafaf18","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.10.4.tgz","fileCount":36,"integrity":"sha512-0LIst+pxAnhIH6dmi4hj1wYLiDfD96TLw+w6PDo6RRt5ICH5CirLgw445UTtq5/AKAXTCLPKavVH2CrjdFzlSg==","signatures":[{"sig":"MEYCIQCgStYco/q2Y59nZqVfpTaLCyN9pOT6mkR+CI56ErkRtgIhAKjp25KqzYlQRSoVZ4yJ7JCR83/Vti6vre+c+uqNSeqD","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQCQvPJjau88zsO3g2hnUI74e/8j75oD0T7qs3XGtN1kAAIhANH5vFWu3+PfJk2nSqoTL6EpghmQnuQAcOjLf/aOlYgo","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.10.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":650976},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"f1ec1b70966c2fb0cb75aaad1fdebbde247cb14a","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.19.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.20.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.10.4_1790182477323_0.10523843695869606","host":"s3://npm-registry-packages-npm-production"}},"0.10.5":{"name":"feature-factory","version":"0.10.5","license":"MIT","_id":"feature-factory@0.10.5","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"930d74a939ac31f06259a1a70d76043b95484ea9","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.10.5.tgz","fileCount":37,"integrity":"sha512-8TaknIh0b8LF07v99DoMNycYjZmTVnfi0gL2Dkxe277kNrxFodjAjLpnNGmoJN/qFLWuwqndrA20wFPZPRPsMQ==","signatures":[{"sig":"MEUCIDDGSEd4FWehVaZJc5KFwTg8XQI4g9Vc0e2DPuLr8ZKCAiEAwTrUqFQIBaJxpR3Tmt2z4Ed4oDbqlRzS30ezhoMYy7c=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQDtGKhv/+HKfk/6x2ppRSpMD/xTRgg66THyc44XXQkyMgIhAIanN1a88coaL03unJal4MkdpySoIo1u7Gbw+fvqhi0l","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.10.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":655389},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"b6f2bbfa9caa8bd04149e2de665ec67a1e0b4a82","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.19.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.21.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.10.5_1790278772301_0.7838085644137265","host":"s3://npm-registry-packages-npm-production"}},"0.10.6":{"name":"feature-factory","version":"0.10.6","license":"MIT","_id":"feature-factory@0.10.6","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"7c4095932226775548d7d0da3f1e1f7a42860b65","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.10.6.tgz","fileCount":37,"integrity":"sha512-R1Lzoe4GwuSEAmrK85hsYUwhfc4APFZykyR8o7rGqf91jKAhddoZQhAesJM+Yjmj5Y7la3PsMXbsUN/SBk6kbg==","signatures":[{"sig":"MEYCIQCS3q3ECd5OELiP7U/8U5YtFneDR3GzPcRNU7xbhacESQIhAMPDMoy9xwvU0DXqA0Nj9ti5rLuVtfS43I665p0fl7O2","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQCeG3fnZpKyEFJzIbyFaGi6jIPafhLXO3HQaLP8VW1nGQIhAO5FNhvp6f9LdvUBR8R7NQGaLDOXwFeHIY2nVPo3phqP","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.10.6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":655889},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"fa5662604338545c9f8cff4035f198f365607a44","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.19.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.21.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.10.6_1790283458676_0.47341055643050334","host":"s3://npm-registry-packages-npm-production"}},"0.10.7":{"name":"feature-factory","version":"0.10.7","license":"MIT","_id":"feature-factory@0.10.7","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"c3e0c1841dfedec0d542d9c30a2342861ac1e993","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.10.7.tgz","fileCount":37,"integrity":"sha512-yvtaL7E+C31lMTG4IgBqM2f9O0fTMHfcS1M/dUxKynuF0R4K/Noh13bZecpATHk9507/c+4YGBFZOrIDgWsA/A==","signatures":[{"sig":"MEYCIQC2Z/Omqyp2wgmE6EseJI/Ap4d7Erwi90oyLDBdFIkZ/wIhALCM38IWwg0ASHVNij/uqoFIoPIvEgPtOObQY9dn9hPh","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIDHYARFuH3x9w4QkNoWSTTXHVQwAt0CvtJEbhx/YytBzAiEA7PCJCpydzaIjsbdAElLtKixzxaVYURf4Xn+nunMkpQo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.10.7","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":662351},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"68f5a03befda5078cbf5017e3357fb2708600563","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.19.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.21.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.10.7_1790309704460_0.27428384660747906","host":"s3://npm-registry-packages-npm-production"}},"0.10.8":{"name":"feature-factory","version":"0.10.8","license":"MIT","_id":"feature-factory@0.10.8","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"ab2f2b17847310c90dcc742188671e22cfa77513","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.10.8.tgz","fileCount":37,"integrity":"sha512-FEKPYrUYG6s2R1eutvlKdt1xA0bT4JhpY5i6Exj43zKPT98UJEKjLej8HFPSYYsjE6zxT4eNi/R8mgL3ZfuOkw==","signatures":[{"sig":"MEYCIQD/9ID2AEua5QHXwOx3asEekuJ4UQglyAteuDahVfQejQIhAPp25/+QnQpztU5f9byNgE+48meMV+PNaOhY0t7NnRJb","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQDKtphkq0nMfLJj+nZIgrqTUoaKQH7Y7ds0xncFXUo8ygIgUt9zOd3T0LlsHHpBPyZBKVGAQukJ06Bz01paZmtWaA0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.10.8","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":666603},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"219e12ead7bcaa41ffe555fa23ef1d182da911da","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.19.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.21.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.10.8_1790340861601_0.1097974400806121","host":"s3://npm-registry-packages-npm-production"}},"0.10.9":{"name":"feature-factory","version":"0.10.9","license":"MIT","_id":"feature-factory@0.10.9","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"homepage":"https://github.com/jasoncarreira/feature-factory#readme","bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"bin":{"factory":"bin/factory.js"},"dist":{"shasum":"ae3f7f19707583806f5f8918e319376606ada1d2","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.10.9.tgz","fileCount":37,"integrity":"sha512-zjiOT55IEmGnn3X1e3+YuEC7RoSVHCBboNa76osEF4ETChfT57nFqnKtG5G9hfi+P5TcvYEm20eS5h1Pz8oeqw==","signatures":[{"sig":"MEUCICkLmfyn6Wwl/5JyxynmEWAuokUoWIEv/EjE+D+fdSVjAiEA9A6NxBWox4DW9wbp2y6mxM/8bII5wErZpYV8yJS9qkE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIBDt4vE77AbZ9/hpdsCFebM538MzA+Wtma5YE0R+muElAiEArQ9fSUQk5g6LAGjwjEKrrbMEuoW1899VzIWYzaBar3o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.10.9","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":681803},"main":"state/index.js","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"0528e01eb32cca4cafeed1a392cbf56768f49c90","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.19.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"_nodeVersion":"24.21.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/feature-factory_0.10.9_1790539762826_0.28318629266885176","host":"s3://npm-registry-packages-npm-production"}},"0.10.10":{"_id":"feature-factory@0.10.10","bin":{"factory":"bin/factory.js"},"bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"dist":{"shasum":"3eddda0f09f31f71f6666774c03789622431d5ec","tarball":"https://registry.npmjs.org/feature-factory/-/feature-factory-0.10.10.tgz","fileCount":37,"integrity":"sha512-HULOL1K6eOU+EOY6RpNIjz+zO9M6XbOUR9EEXyFUmnX1HWmyRtLAdtlpM0sAFB5C85ha7AEDhbSe8f3EpxRK8Q==","signatures":[{"sig":"MEUCIQDqxD8OtOAwJUC9aMhQT8bDVkFzTS7kldUiGpHBu96GNAIgdmieIktAlZ2WQNhxqgk185YEsNiwbpgFvTLx25SSOcg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDADqNtMWXQHuBAk7kbz/cjIO4KImaJ+7JHXwxSJSoG3QIhANwThWgTgPxWgy7n7Bgmry9z6JDdiVrxARvX0FrysSgo"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/feature-factory@0.10.10","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":689683},"main":"state/index.js","name":"feature-factory","type":"module","engines":{"node":">=22"},"exports":{".":"./state/index.js"},"gitHead":"1e09b4b29734b1ea606729153218d4a00f8ab59c","license":"MIT","scripts":{"test":"FACTORY_PUBLISHING_IDENTITY=factory-test node --import ../../tools/resolve-guard.mjs --test test/*.test.js"},"version":"0.10.10","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"e08fe88d-99b5-4a69-9345-7923ec9e1da9"}},"homepage":"https://github.com/jasoncarreira/feature-factory#readme","repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"_npmVersion":"11.19.0","description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","directories":{},"maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"_nodeVersion":"24.21.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/feature-factory_0.10.10_1790812424485_0.36967340195220144"}}},"time":{"created":"2026-08-16T15:32:12.279Z","modified":"2026-09-30T23:53:44.873Z","0.7.0":"2026-08-16T15:32:12.491Z","0.7.1":"2026-08-20T12:01:39.889Z","0.7.2":"2026-08-21T00:51:34.158Z","0.7.3":"2026-08-25T21:44:26.958Z","0.7.4":"2026-08-27T13:02:40.728Z","0.7.5":"2026-08-27T18:52:42.767Z","0.8.0":"2026-08-28T02:22:35.727Z","0.8.1":"2026-09-03T14:11:06.976Z","0.8.2":"2026-09-04T01:42:02.956Z","0.8.3":"2026-09-05T00:59:15.508Z","0.8.4":"2026-09-10T23:12:36.399Z","0.8.5":"2026-09-11T02:07:22.691Z","0.8.6":"2026-09-11T04:47:34.915Z","0.8.7":"2026-09-12T01:47:20.573Z","0.8.8":"2026-09-16T18:26:47.802Z","0.8.9":"2026-09-17T01:53:29.502Z","0.9.0":"2026-09-17T21:25:39.360Z","0.9.1":"2026-09-19T00:19:04.711Z","0.9.2":"2026-09-19T14:14:01.375Z","0.10.0":"2026-09-22T02:58:18.722Z","0.10.1":"2026-09-22T19:02:14.003Z","0.10.2":"2026-09-23T01:06:37.240Z","0.10.3":"2026-09-23T12:40:52.532Z","0.10.4":"2026-09-23T16:54:37.440Z","0.10.5":"2026-09-24T19:39:32.411Z","0.10.6":"2026-09-24T20:57:38.761Z","0.10.7":"2026-09-25T04:15:04.592Z","0.10.8":"2026-09-25T12:54:21.692Z","0.10.9":"2026-09-27T20:09:22.929Z","0.10.10":"2026-09-30T23:53:44.570Z"},"bugs":{"url":"https://github.com/jasoncarreira/feature-factory/issues"},"license":"MIT","homepage":"https://github.com/jasoncarreira/feature-factory#readme","repository":{"url":"git+https://github.com/jasoncarreira/feature-factory.git","type":"git","directory":"packages/feature-factory"},"description":"Durable, observed control plane for /feature runs. Host-agnostic: no opencode dependency.","maintainers":[{"name":"jcarreira","email":"jcarreira@gmail.com"}],"readme":"# feature-factory\n\nA durable, observed control plane for running a feature from idea to pull request through a chain of\nfocused agents, with human approval gates. Host-agnostic, zero dependencies.\n\n```sh\nnpm install feature-factory\n```\n\nShips three things:\n\n| | |\n| --- | --- |\n| `bin/factory.js` | the `factory` CLI — fourteen commands, each state change one checked transition |\n| `WORKFLOW.md` | the canonical, host-agnostic workflow contract |\n| `agents/` | eleven specialist definitions dispatched by a host adapter |\n\nThis package owns `WORKFLOW.md`; it does not ship a platform `SKILL.md`. Each adapter owns its own\nhost binding and copies this workflow beside that skill at build/pack time. Install\n`opencode-feature-factory` or `prime-agent-feature-factory` for a supported host, or build an adapter\nthat loads the complete workflow and drives all durable state changes through the CLI.\n\n## Infrastructure failures and attempts\n\nA confirmed host-origin availability or transport failure does not spend a specialist attempt. The active\ndriver permits one same-attempt recovery for the canonical role and subject only when the host proves\nexecution never started or can recover the same child/session. Unbudgeted research and design create no\nattempt. A second consecutive failure parks the run. The count is memory-only and resets with the driver,\nbut resume and reset never prove that prior work did not start: the next driver must recover or prove the\nsame prior invocation safe before dispatch. Child text, unknown errors, and excluded auth, quota,\nrate-limit, and configuration failures never trigger a free retry or duplicate possibly-started work.\n\n## Repository command configuration\n\nA repository operator may provide optional `$O/.factory.json`, where `O` is the physically\nresolved Git top level:\n\n```json\n{\n  \"resolve\": \"<non-empty shell command>\",\n  \"verify\": \"<non-empty shell command>\",\n  \"publish\": \"<non-empty shell command>\",\n  \"pr_draft\": true,\n  \"verify_timeout_ms\": 900000,\n  \"bootstrap\": \"<non-empty shell command>\",\n  \"bootstrap_timeout_ms\": 900000\n}\n```\n\nThe root has two required properties, `resolve` and `verify`, and six optional properties: `publish`,\n`pr_draft`, `verify_timeout_ms`, `bootstrap`, `bootstrap_timeout_ms`, and `max_retries`. Required commands and any present\n`publish` or `bootstrap` are non-empty strings. There is no `publishing_identity` key, and a file carrying one is malformed because the\noptional set is closed. A present `pr_draft` must be a JSON boolean and omission means `true`. Both timeouts are\npositive safe integers. `bootstrap_timeout_ms` requires `bootstrap`.\nA present `max_retries` must be a positive integer. It is the run's attempt budget when `init` runs\nwithout `--max-retries`, which still outranks it; omission leaves the default `3`.\nEach omitted timeout independently defaults to `900000`; neither shares the other's budget. The file is\noperator-owned, committed, and protected as a privileged path: a run cannot create, write, merge,\narchive, package, or repair it.\n\nThe publishing identity is not a config key. `factory init` resolves it from `--publishing-identity\n<account>` or the inherited `FACTORY_PUBLISHING_IDENTITY`, refuses when neither supplies at least one\ncharacter, and records the resolved value immutably in `run.json`, where `status --json` reports it as\n`publishing_identity`. The account a run publishes as is a property of the environment it runs in, not of\nthe repository, and a tracked file cannot hold two values for one repository published from both a\nmaintainer's checkout and an automated host. Absence refuses rather than skipping the guard, so a forgotten\nvalue stops the run instead of publishing under whatever credential the host happens to carry. Never derive\nit from `gh`, the token, stored authentication, or Git configuration: an expectation read from the\ncredential being checked would always match.\n\nValidation refuses the first matching defect in this order: unreadable or invalid JSON, a non-object root, or unknown keys; invalid `pr_draft`; invalid `bootstrap`; `bootstrap_timeout_ms` without `bootstrap`; invalid `bootstrap_timeout_ms`; invalid `verify_timeout_ms`; missing or invalid required entries; invalid `publish`; then invalid `max_retries`.\n\nThe named forms are `.factory.json entry 'pr_draft' must be a boolean`, `.factory.json entry 'bootstrap' must be a non-empty string`, `.factory.json entry 'bootstrap_timeout_ms' requires a declared bootstrap command`, `.factory.json entry 'bootstrap_timeout_ms' must be a positive integer`, `.factory.json entry 'verify_timeout_ms' must be a positive integer`, and `.factory.json entry 'max_retries' must be a positive integer`.\n\nA present invalid, unreadable, incomplete, wrong-type, whitespace-only, or unknown-property config refuses closed.\n\nFresh init captures the effective `pr_draft` value only after the cloned repository config validates,\nand stores that boolean immutably in `run.json`; init JSON and plain output do not change. Legacy\nmanifests without the key remain keyless and behave as `true`. Status alone adds effective\n`pr_draft: boolean` in JSON and `pr_draft: true|false` in plain output. Step 6 reads that status value:\n`true` (including legacy omission) creates a draft PR, while explicit `false` creates a ready-for-review\nPR without `--draft`. Publication does not reread the live config.\n\n`resolve`, `bootstrap`, and `verify` are consumed now. `resolve` runs as one ordinary shell step with the configured string submitted\nunchanged, repository-root cwd, inherited environment plus the exact admitted request in\n`FACTORY_INPUT`, and no positional argument or structured stdin. Empty stdout means the input was not\nrecognized. Non-empty stdout is the direct,\nunchanged `ISSUE_PAYLOAD`: one JSON object containing a valid canonical top-level string `run_id`, a\nnon-empty string `title`, and a string `body` — all three validated before the run id is bound or anything\nis dispatched — where `run_id`\nselects the run and reaches `story-reader` without extraction, wrapping, reserialization, or\nnormalization. The value matches `^[a-z0-9](?:[a-z0-9._-]*[a-z0-9])?$`; digit-only values are positive\ndecimal without leading zeroes.\n\nA resolver does not have to look anything up. When the caller already holds the work item — a controller\ndispatching an item it rendered itself, or a tracker whose content is already in the launch environment —\nthe resolver is a transport rather than a lookup, and the whole of it is one `printf`:\n\n```sh\n[ -n \"$MY_WORK_ITEM_JSON\" ] && { printf %s \"$MY_WORK_ITEM_JSON\"; exit 0; }\n# otherwise fall through to whatever lookup this repository declares\n```\n\nUse `printf %s` and not `echo`, which appends a newline and in some shells interprets backslash escapes,\ncorrupting a `body` that contains them. Gating the branch on a variable lets one config serve both callers:\nthe caller that supplies the item sets it, and a caller that supplies only a reference takes the declared\nlookup unchanged, so adding the branch changes no existing behavior. Because the resolver chooses `run_id`,\na caller supplying its own item also chooses the sandbox name, feature-branch suffix, and manifest candidate\n— so giving it a namespace of its own, such as `chainlink-1327`, makes collision with the tracker's own\nnumbering unrepresentable rather than something a lookup has to detect.\n\nA resolver that recognizes a reference it cannot serve must exit non-zero rather than exit zero with empty\nstdout. Exit status is observable, so those two results are distinguishable — which is precisely why the\nchoice matters. The ambiguity arises only when an in-scope but unserviceable reference is *reported* as exit\nzero with empty stdout, because that is already the contract's signal for *this is not my reference*: the run\nthen continues to ticket, design, and free-text derivation from the request, and for a bare id that names no\nworkflow, outcome, or acceptance criteria, so it reaches Gate 1 with nothing to approve and parks there. A\nnon-zero exit instead refuses immediately, names the reference, and creates no session or run. Only the\nresolver author knows which of the two cases it is in, so the contract cannot make the choice for it.\n\nA `needs-human` terminalization is followed by a control-plane snapshot: the driver copies the run\ndirectory to `$O/.factory/.parked/<R>` immediately after recording the park. A parked run waits for\noutside intervention, and its control plane otherwise exists only inside the sandbox, so anything that\nremoved the sandbox destroyed the manifest and every accepted gate with it. `.parked` cannot be a run\nid, so a snapshot never occupies the completed archive at `$O/.factory/<R>` and never blocks\nre-initialising the same run id. It is published by a staged, verified swap, so a failed later park cannot degrade the last good\nsnapshot. A failed snapshot is reported and never prevents the park. `blocked`\nand `partial` are not snapshotted. A retained sandbox resumes directly; when that sandbox is lost,\n`factory restore <R> --repo <O> --from refs/remotes/<remote>/<feature-branch>` rebuilds a parked,\nlockless sandbox from the snapshot and the exact pushed feature ref. It reports every active slice reset\nto `pending` rather than claiming branch-local work survived.\n\nQualified status reports `park_snapshot` for an unchanged live park: the published path, or `null` when no\nmatching snapshot exists. A restored generation deliberately reports `null` because its manifest and path\nbindings changed; `status.restore` carries its source digest, feature commit, resets, and invalidations.\nMalformed config, malformed payload, a non-zero exit, or unavailable exit status refuses before any\nrun effect and never falls back:\n\n```text\ninvalid factory config: .factory.json; no session or run created.\nfactory config entry 'resolve' returned malformed payload for reference <reference>; no session or run created.\nfactory config entry 'resolve' failed for reference <reference> with exit status <status>; no session or run created.\nfactory config entry 'resolve' failed for reference <reference>; exit status unavailable; no session or run created.\n```\n\nResolver diagnostics name `resolve`, the status classification, and the admitted reference bounded to 200\ncharacters; neither the configured or expanded\ncommand line, shell diagnostics, nor credentials are printed, logged, or persisted. Credential values\nstay in inherited environment variables and never in the config. The resolver contract adds no bridge,\nparser service, command runner, capture or stderr policy, output channel or size policy, buffering,\ntruncation, redaction, timeout, retry, cache, payload transport, or session behavior.\n\n### Sandbox bootstrap\n\nOnly the CLI executes configured `bootstrap`: once during fresh init after clone, containment, and PR-base observation but before manifest publication, and again on every explicit resume while the run remains parked. It also runs immediately before every configured `verify` execution, in the slice or integration worktree that verify runs in, so `verify` always sees bootstrap output installed from the tree it checks. The exact configured string runs unchanged with `shell: true`, inherited environment and stdin, cwd exactly the selected sandbox, and child stdout and stderr both routed to CLI stderr. Init JSON stdout therefore remains exactly one response object. Bootstrap has its own configured timeout or independent `900000` millisecond default, with no retry and no use of the verify budget.\n\nAfter every attempt, the CLI checks tracked worktree and index paths only and ignores untracked dependency output. Unobservable tracked state refuses before dirty tracked paths; dirty paths refuse before unavailable or nonzero exit, and diagnostics name exact repository-relative paths. A clean numeric zero stores paired `bootstrap_command` and `bootstrap_exit` manifest evidence. The command is exact; the exit is a non-negative integer or `null`. Ordinary transitions preserve the pair, and status output does not expose it.\n\nA failed, timed-out, dirty, or unobservable fresh init emits no JSON stdout, retains the deterministic sandbox, and leaves `run.json` absent. Configured resume first binds exact raw manifest bytes, validated parked state, a forward timestamp, and the exact fresh owner. Clean zero records evidence and unparks while preserving progress and the historical terminal result. Ordinary failure with intact bindings records integer or `null` evidence, advances the timestamp, remains `needs-human`, preserves progress and the historical result, and refuses so a later explicit resume reruns bootstrap. Byte mutation or owner loss preserves current state and ownership, records no evidence, and does not unpark. Factory claim, force-steal, heartbeat refresh, and release serialize with resume publication through `run-json.lock`.\n\nWhen both bootstrap keys are absent, init and resume are exact no-ops for bootstrap: no execution, manifest fields, output, or response-shape change.\n\nBootstrap never runs during resolver intake, merge verification or replay, direct repository verification, slice observation, Gate 3, effective push, configured publication, push, or PR creation. Bootstrap does not mediate configured publication, effective-push, push, PR, or Gate 3 behavior.\n\nAfter a slice merge is successfully and atomically recorded, `verify` starts in the exact recorded\nintegration worktree. Its configured string is submitted unchanged as one ordinary shell command with\nthat worktree as cwd and inherited environment and stdio. Stdout and stderr are visible, informational,\nand unparsed; they are not captured or persisted. Numeric child exit status is authoritative: zero\nsucceeds and non-zero fails repository verification; no numeric status is canonical unavailable\nevidence. Each repository shell attempt gets the full configured timeout. A merge or replay invocation\nexecutes at most twice, and retries only a first unavailable result after freshly proving the unchanged\nworktree, merge SHA at `HEAD`, and clean tree. Resolver, slice, and Gate 3 commands receive neither this\ntimeout nor this retry. The observation uses the existing canonical `evidence/test-verifier.json` schema,\nbound to the current merged head and the immutable root base.\n\nIf `.factory.json` is absent, intake declares no resolver and init and resume perform no bootstrap. After\na recorded merge the factory silently returns its previous response with no repository command,\nevidence write, or new output. A post-record\nfailure leaves the merged row and its slice evidence and review unchanged and stops before the next wave.\nProduction defects, repair exhaustion, dirty or moved safety failures, invalid config, and malformed,\nstale, foreign, wrong-command, missing-field, or inconsistent evidence terminalize `needs-human`; clean,\nunchanged second-unavailable repository verification instead follows the nonterminal exhausted/release\ncontract below. Only a confirmed test-only finding can use the bounded test-file-only repair path, with a\nseparate commit and fresh repository verification.\n\nCanonical evidence has exactly four classifications. `green` has exact run, `test-verifier` subject,\ncurrent merged head, and unchanged `verify` command binding, observed integer exit zero, and\n`review_ready: true`. `failed` has that exact binding with an observed nonzero integer exit, or observed\nzero that is not review-ready. `unavailable` has that exact binding and `observed: false`, `exit: null`,\nand `skipped_reason: null`. Missing, unreadable, malformed, foreign, stale-head, wrong-command,\nmissing-field, or internally inconsistent evidence is `unknown`. Only `unavailable` is replay-eligible.\nA later invocation may replay the exact same-SHA merge only with no active repair, a freshly verified\nexact integration worktree on the recorded feature branch, the immutable merge SHA still at `HEAD`, and\na freshly observed clean tree. Green and failed evidence is reused; unknown evidence never executes. The\nmerged slice is never reopened, re-seeded, re-observed, remerged, or re-dispatched.\n\nTwo clean, unchanged unavailable executions terminate the current CLI and driver invocations, not the\ndurable run. The driver quiesces all tasks and heartbeats, releases exactly its owning session, and uses\nqualified status to prove `running`, null terminal result, and no ownership before reporting\n`repository-verify-exhausted`. Release or ownership-verification failure reports `retained-lock-error`\nwithout a resumability claim. A later invocation repeats all normal guards, claims with its actual\nhost-exported session ID, verifies ownership, and only then reconciles the same SHA. That value may equal\nthe prior value; verified release followed by a new verified claim establishes freshness.\n\nGate 3 always runs a separate fresh integrated `test-verifier` observation at the current head. It\noverwrites canonical evidence through the existing command mode and never shares, substitutes, or\noptimizes from post-merge evidence, even when the head is unchanged.\n\n## Restoring a lost parked sandbox\n\nRun restore from the canonical operator repository, not from a replacement checkout:\n\n```sh\nfactory restore <run-id> --repo <operator-repository> \\\n  --from refs/remotes/<remote>/<recorded-feature-branch> --json\n```\n\nThe source must be the canonical `$O/.factory/.parked/<run-id>` snapshot. The feature ref must be a full\nremote-tracking ref whose branch suffix exactly matches the manifest and whose commit is still advertised\nby that remote's push endpoint, exactly equal to the operator effective push endpoint. Restore validates\nthat snapshot, refuses symlinks that escape its control plane, clones the exact derived sandbox, aligns and\nrechecks the operator's effective push target, and proves every preserved merged-slice Git and evidence\nbinding against the pushed head. It omits the old root session lock and publishes the transformed manifest\nlast. The run stays parked and no repository-configured bootstrap runs. Nonmerged slices with physical\nbranch or worktree state reset to `pending`, and the command reports them. Stale HEAD-bound validator\napproval is invalidated. Gate 3 and test-verifier approval are always invalidated because canonical\npublication evidence names the prior physical generation; canonical verifier records are omitted from the\ncopy. The staged slice projection must still match the Brief-bound plan digest and recorded amendments.\nThe durable `status.restore` record identifies the source inventory and restored commit. Because the new\ngeneration has different paths and provenance, `status.park_snapshot` is `null` after a successful restore.\nClaim the new lock and use the ordinary resume sequence only after reviewing those losses.\n\n## Resuming a parked run\n\nA top-level `needs-human` status is a parked stop, not a final result. `completed`, `partial`, and\n`blocked` remain final. Fix the external cause, then preserve this order: bind the intended retained\nsandbox and validate its manifest and containment; run the post-selection exact-ref-absent guard;\ncomplete effective-push proof; accept branch provenance, worktree binding, seed ancestry, cleanliness,\nrecovery, and every operator-ref recheck; rerun the final exact-ref guard immediately before claim;\nclaim or justifiably steal and verify fresh ownership plus the unchanged parked result; run\nan optional `factory amend-paths <run-id> <slice-id> --add <path> [--add <path> ...] --reason <text>\n--session <id> --repo <sandbox>` only when the verified cause is missing ownership on an unmerged slice;\nthen run `factory resume <run-id> --session <id> --repo <sandbox>` and verify running status, unchanged historical result, real\nnext action, and the same owner; replay only existing post-lock reconciliation for an already-recorded\nmerge; then continue solely from the newly qualified `status.next`.\n\nStatus remains readable while parked, and lock claim, justified steal, heartbeat, and owning release\nremain available for ordered qualification. Every other effectful command refuses until explicit\nresume. Without configured bootstrap, resume changes only `status` and `updated_at`. With configured\nbootstrap, it also records the paired command and result under the bound transition described above.\nBoth paths preserve the original terminal reason and all progress. A resumed recorded merge still traverses the existing clean-head, retry-safety, evidence, and\nrepository-verification path. An unresolved repair-journal record is separate and remains\npublication-blocking. If the cause was not fixed, the run may park again with the same reason.\n\nThe optional amendment runs while the status remains `needs-human`, after fresh exact owner\nverification and before resume. It appends repository-relative, nonprivileged paths in request order and\nrecords their verbatim reason, session, and timestamp in `path_amendments`; the original path prefix and\n`test_plan` stay immutable. It never resolves or requires path existence, and another slice may already\nown the same path. Duplicate, target-already-owned, malformed, privileged, replayed, or merged-slice\nrequests refuse atomically. Resume never amends or reseeds. A merge continues to refuse every unamended\nor privileged changed path.\n\nA parked slice that exhausted its effective limit can be reopened for one more attempt through\n`factory grant-retry <run-id> <slice-id> --scope slice|all [--max-retries N] --reason <text> --session <id> --repo <sandbox>`;\n`--max-retries` (with `all` only) sets the new run-wide limit in one call instead of raising it by one.\nSlice scope raises only the target's additive allowance. All scope raises `max_retries` for pending later\nwaves too, but refuses when another slice is blocked or an exhausted post-merge repair record exists. Both\nscopes reopen only the named slice after exact owner, snapshot, REJECT, evidence, base, current clean head,\nand immutable attempt archives. A legacy run missing one prepares it without granting, then requires a\nfresh snapshot and a second grant invocation. Exhaustion parks with reason `blocked-after-retries` rather\nthan terminalizing `partial`. The grant durably fences the prior canonical snapshot before committing its\nmanifest, then removes it only after the commit is proved; restore and parked mutations refuse any\ninterrupted fence. Run `factory snapshot <run-id> --repo <operator>` and requalify it before the separate\nexplicit resume. Restored blocked slices whose physical refs were intentionally cleared do not qualify.\n\n`resolve` and `verify` are consumed now, and the run's recorded `publishing_identity` is compared at the publication guards. Step 6 resolves one selection: a nonblank inherited `FACTORY_PUBLISHING_COMMAND` selects its exact string; that variable set blank or whitespace selects the default; when it is unset, configured `publish` wins if present; otherwise the default wins. Only a selected nondefault command replaces `gh pr create`, after the factory-owned exact push and post-push identity guard. It receives exact `PR_BASE`, `FEATURE_BRANCH`, `PR_DRAFT`, `PR_TITLE`, and absolute `PR_BODY_FILE` environment values. Only exit zero with an absolute HTTPS URL on the last nonempty stdout line is recordable; every other result parks with exact reason `selected publishing command outcome indeterminate; re-observe whether the pull request exists before retry` and no fallback.\nEffective push-target capture and comparison are active through the package-owned `factory effective-push` command; they are not deferred to configured `publish`.\nThe recorded `publishing_identity` is read from `status` exactly as reported, without trimming,\nnormalization, case-folding, or reserialization. `init` refuses when neither the flag nor the environment\nsupplies at least one character, so a created run always carries one; only a manifest written before 0.8.0\ncan report `null`. `publishing_identity` is a recorded run field reported by `status`, resolved by `init` from a flag or the environment. The independent `factory effective-push` command adds no state or flag.\n\nWith a recorded identity, every mode checks it at exactly three boundaries: immediately\nafter verified post-lock ownership, or immediately after an explicit resume is verified running with\nthe same fresh owner and before reconciliation or other work; immediately before `git push`, after\neffective push-target equality; and immediately before the selected PR-creation command, after the\nfactory-owned exact push is known successful. No operation intervenes across a guard boundary. Only a manifest written before 0.8.0, which can\nreport `null`, skips all three guards; an absent config does not affect them.\n\nBefore each guard, inherited `GH_TOKEN` must exist and contain at least one character. Missing or empty\nmeans identity is unobservable without invoking `gh`, the network, stored authentication, credential\nqueries, or any fallback. A prepared environment submits exactly this command as one\nordinary host shell step with cwd exactly `RUN_REPO`, inherited environment, and no stdin:\n\n```sh\nfactory identity \"$R\" --json --repo \"$RUN_REPO\"\n```\n\nThe CLI runs the read-only network probe `gh api --method GET /user --jq .login` itself, with separate\nstdout and stderr pipes, so a host whose shell tool combines the two streams can still run the guard. It\nreturns JSON whose `reason` is null on a match and is otherwise the complete rendered park reason.\n\nThe probe's stdout bytes, stderr bytes, and numeric status are parsed strictly. Only numeric zero, empty\nstderr, and exactly one ASCII GitHub login plus one LF are observable; the required LF alone is removed,\nthen the raw login is compared exactly and case-sensitively with the raw declaration. `gh auth status`\ndoes not prove the publishing identity.\n\nA mismatch names the safely rendered declared and observed values and says to authenticate as the\ndeclared account; an unobservable result names the safely rendered declaration and says to launch with\ninherited `GH_TOKEN` for it. Values use deterministic ASCII-only JSON-string rendering, including\nlowercase `\\uXXXX` escapes outside printable ASCII. The complete rendered reason is transported as one\nshell-safe argv token and the sole `--reason` value. The token, raw stdout or stderr, diagnostics, status,\ntargets, helper output, and environment are never exposed, and the factory never manages credentials or\ntransport.\n\nEither refusal quiesces outstanding work, parks through existing `needs-human`, verifies the exact\npersisted reason and owner, releases that owner, verifies the lock absent, and retains the sandbox. After\nthe environment is fixed, a later driver binds the retained sandbox and repeats every selection,\nmanifest, containment, config, effective-push, provenance, branch, worktree, cleanliness or recovery,\nand exact-ref precheck; makes and verifies a fresh claim with its own `FACTORY_SESSION_ID`; runs exactly\n`factory resume \"$R\" --session \"$FACTORY_SESSION_ID\" --repo \"$RUN_REPO\"`; verifies running status, the\nunchanged historical result, real next action, and same owner; performs existing post-resume\nreconciliation; and continues only from the newly qualified `status.next`. It never reuses the released\nsession.\n\nPublishing-identity verification is enforcement because it prevents false-green or wrong-account\npublication. Credential provisioning and helper setup are instruction only. Existing push,\n`factory pr`, Gate 3, merge, and approval semantics remain unchanged. The live config\nis not part of this package and no generated config or resolver asset is shipped. See the repository's\n[operator guide](https://github.com/jasoncarreira/feature-factory/blob/main/OPERATING.md) for the\nshared inherited-token helper recipe; it does not acquire, store, install, or repair credentials.\n\n## Effective push target\n\n```text\nfactory effective-push <bootstrap|check> <operator-repository> <sandbox-repository>\n```\n\nThe command accepts exactly those three positional arguments and no options. `bootstrap` captures the\noperator's effective push target, configures the sandbox push URL from it, then freshly captures both\nrepositories and compares them exactly. `check` freshly captures both targets and compares without\nconfiguration. Both modes use shell-free Git subprocesses, write no output on success, and retain the\nsandbox on a fixed redacted failure. Captured targets and child diagnostics are never returned, logged,\npersisted in factory state, printed, or attached as an error cause. The command is independent of\n`publishing_identity` and adds no run state or flag. After the factory-owned exact push and post-push\nidentity guard, Step 6 resolves one PR-creation selection: a nonblank inherited\n`FACTORY_PUBLISHING_COMMAND` selects its exact string; that variable set blank or whitespace selects the\ndefault; when it is unset, configured `publish` wins if present; otherwise the default wins. Only the\nselected nondefault command replaces `gh pr create`, so a repository declaration cannot leave a host with\nnothing to delegate to unable to publish at all.\n\n## Why the code exists at all\n\nAlmost all of this system is prose. Code exists only where prose cannot enforce something:\n\n- **Agents cannot reliably hand-write a schema-perfect `run.json`**, so every state change goes\n  through `lock → read → validate → apply → validate → compare-and-swap → rename`, and nothing else\n  writes the manifest.\n- **Verification exists only where its absence produces a false green.** With a human at the gate,\n  someone sees the diff. In an autonomous run nobody does, so a review must name the commit it\n  judged, a merge must prove it contributed exactly what was reviewed, and a test result must have\n  been observed rather than reported.\n\nRun state lives at `<repo>/.factory/<run-id>/run.json`, which must be gitignored: a tracked\ncontrol plane puts manifest churn in every slice diff and trips the privileged-path refusal on every\nmerge.\n\n## The read-only API\n\nFor tools that display run state. Everything here reads; nothing writes.\n\n```js\nimport { readRun, readRunUnchecked, nextAction, validateRun, RUN_KEYS } from \"feature-factory\";\n```\n\n`readRun` validates and throws; `readRunUnchecked` reports a broken record instead of refusing to\nload it, so a diagnostic can show an operator what is wrong. `nextAction` derives what happens next,\nand is the same function `factory status` uses — so a display cannot disagree with the CLI.\n\nThe write path is deliberately not exported. Changing state means calling the CLI.\n\nSee the [repository](https://github.com/jasoncarreira/feature-factory) for the full command\nreference and design notes.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}