productfoo 0.0.0-stage → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +338 -2
- package/bin/foo +3 -0
- package/bin/foo.mjs +42 -0
- package/commands/bug.md +31 -0
- package/commands/discovery.md +28 -0
- package/commands/ideate.md +27 -0
- package/commands/init.md +28 -0
- package/commands/pitch.md +27 -0
- package/commands/preview.md +25 -0
- package/commands/research.md +31 -0
- package/commands/roast.md +27 -0
- package/commands/spec.md +30 -0
- package/config/pricing.yaml +198 -0
- package/config/routing-policy.yaml +171 -0
- package/dist-public/src/activeModel.d.ts +83 -0
- package/dist-public/src/activeModel.js +331 -0
- package/dist-public/src/agentAdapters.d.ts +122 -0
- package/dist-public/src/agentAdapters.js +178 -0
- package/dist-public/src/agentState.d.ts +43 -0
- package/dist-public/src/agentState.js +177 -0
- package/dist-public/src/bugCapsule.d.ts +94 -0
- package/dist-public/src/bugCapsule.js +227 -0
- package/dist-public/src/bugCapture.d.ts +26 -0
- package/dist-public/src/bugCapture.js +251 -0
- package/dist-public/src/bugOwnerLog.d.ts +93 -0
- package/dist-public/src/bugOwnerLog.js +304 -0
- package/dist-public/src/bugReportStore.d.ts +48 -0
- package/dist-public/src/bugReportStore.js +860 -0
- package/dist-public/src/bugSpecContext.d.ts +7 -0
- package/dist-public/src/bugSpecContext.js +129 -0
- package/dist-public/src/channelFreshness.d.ts +25 -0
- package/dist-public/src/channelFreshness.js +194 -0
- package/dist-public/src/cli.d.ts +30 -0
- package/dist-public/src/cli.js +1667 -0
- package/dist-public/src/cliArgs.d.ts +7 -0
- package/dist-public/src/cliArgs.js +44 -0
- package/dist-public/src/codeCatalog.d.ts +41 -0
- package/dist-public/src/codeCatalog.js +197 -0
- package/dist-public/src/commandContract.d.ts +84 -0
- package/dist-public/src/commandContract.js +390 -0
- package/dist-public/src/commandUsage.d.ts +3 -0
- package/dist-public/src/commandUsage.js +30 -0
- package/dist-public/src/commands/agent.d.ts +60 -0
- package/dist-public/src/commands/agent.js +1353 -0
- package/dist-public/src/commands/asp.d.ts +8 -0
- package/dist-public/src/commands/asp.js +669 -0
- package/dist-public/src/commands/evalCmd.d.ts +4 -0
- package/dist-public/src/commands/evalCmd.js +405 -0
- package/dist-public/src/commands/login.d.ts +25 -0
- package/dist-public/src/commands/login.js +94 -0
- package/dist-public/src/commands/loop.d.ts +16 -0
- package/dist-public/src/commands/loop.js +619 -0
- package/dist-public/src/commands/reconcile.d.ts +41 -0
- package/dist-public/src/commands/reconcile.js +292 -0
- package/dist-public/src/commands/runtime.d.ts +1 -0
- package/dist-public/src/commands/runtime.js +36 -0
- package/dist-public/src/commands/scanRedact.d.ts +8 -0
- package/dist-public/src/commands/scanRedact.js +266 -0
- package/dist-public/src/commands/setup.d.ts +28 -0
- package/dist-public/src/commands/setup.js +398 -0
- package/dist-public/src/commands/shared.d.ts +17 -0
- package/dist-public/src/commands/shared.js +147 -0
- package/dist-public/src/commands/source.d.ts +1 -0
- package/dist-public/src/commands/source.js +134 -0
- package/dist-public/src/commands/specCmd.d.ts +24 -0
- package/dist-public/src/commands/specCmd.js +794 -0
- package/dist-public/src/commands/update.d.ts +61 -0
- package/dist-public/src/commands/update.js +244 -0
- package/dist-public/src/comprehensionSignal.d.ts +20 -0
- package/dist-public/src/comprehensionSignal.js +166 -0
- package/dist-public/src/conductor/diversity.d.ts +48 -0
- package/dist-public/src/conductor/diversity.js +423 -0
- package/dist-public/src/conductor/engine.d.ts +7 -0
- package/dist-public/src/conductor/engine.js +295 -0
- package/dist-public/src/conductor/families/ideate.d.ts +2 -0
- package/dist-public/src/conductor/families/ideate.js +255 -0
- package/dist-public/src/conductor/families/interview.d.ts +2 -0
- package/dist-public/src/conductor/families/interview.js +39 -0
- package/dist-public/src/conductor/families/specSwarm.d.ts +2 -0
- package/dist-public/src/conductor/families/specSwarm.js +146 -0
- package/dist-public/src/conductor/familyDelivery.d.ts +6 -0
- package/dist-public/src/conductor/familyDelivery.js +37 -0
- package/dist-public/src/conductor/familyPackArtifact.d.ts +4 -0
- package/dist-public/src/conductor/familyPackArtifact.js +260 -0
- package/dist-public/src/conductor/ideateDecision.d.ts +6 -0
- package/dist-public/src/conductor/ideateDecision.js +237 -0
- package/dist-public/src/conductor/pack.d.ts +26 -0
- package/dist-public/src/conductor/pack.js +75 -0
- package/dist-public/src/conductor/types.d.ts +111 -0
- package/dist-public/src/conductor/types.js +7 -0
- package/dist-public/src/configPath.d.ts +2 -0
- package/dist-public/src/configPath.js +7 -0
- package/dist-public/src/discoveryArtifacts.d.ts +54 -0
- package/dist-public/src/discoveryArtifacts.js +467 -0
- package/dist-public/src/discoveryCommand.d.ts +127 -0
- package/dist-public/src/discoveryCommand.js +2148 -0
- package/dist-public/src/discoveryConnections.d.ts +339 -0
- package/dist-public/src/discoveryConnections.js +613 -0
- package/dist-public/src/discoveryDocs.d.ts +129 -0
- package/dist-public/src/discoveryDocs.js +577 -0
- package/dist-public/src/discoveryEvidence.d.ts +59 -0
- package/dist-public/src/discoveryEvidence.js +198 -0
- package/dist-public/src/discoveryFireflies.d.ts +25 -0
- package/dist-public/src/discoveryFireflies.js +551 -0
- package/dist-public/src/discoveryGmail.d.ts +12 -0
- package/dist-public/src/discoveryGmail.js +466 -0
- package/dist-public/src/discoveryGong.d.ts +12 -0
- package/dist-public/src/discoveryGong.js +491 -0
- package/dist-public/src/discoveryLearningRouting.d.ts +90 -0
- package/dist-public/src/discoveryLearningRouting.js +405 -0
- package/dist-public/src/discoveryMatching.d.ts +26 -0
- package/dist-public/src/discoveryMatching.js +73 -0
- package/dist-public/src/discoveryOutlook.d.ts +12 -0
- package/dist-public/src/discoveryOutlook.js +492 -0
- package/dist-public/src/discoveryProcess.d.ts +221 -0
- package/dist-public/src/discoveryProcess.js +703 -0
- package/dist-public/src/discoveryProof.d.ts +143 -0
- package/dist-public/src/discoveryProof.js +529 -0
- package/dist-public/src/discoveryProviders.d.ts +152 -0
- package/dist-public/src/discoveryProviders.js +756 -0
- package/dist-public/src/discoveryReadiness.d.ts +219 -0
- package/dist-public/src/discoveryReadiness.js +672 -0
- package/dist-public/src/discoveryReconcile.d.ts +57 -0
- package/dist-public/src/discoveryReconcile.js +424 -0
- package/dist-public/src/discoverySlack.d.ts +12 -0
- package/dist-public/src/discoverySlack.js +452 -0
- package/dist-public/src/discoverySources.d.ts +56 -0
- package/dist-public/src/discoverySources.js +322 -0
- package/dist-public/src/discoverySync.d.ts +52 -0
- package/dist-public/src/discoverySync.js +151 -0
- package/dist-public/src/discoverySynthesis.d.ts +57 -0
- package/dist-public/src/discoverySynthesis.js +215 -0
- package/dist-public/src/discoveryTeams.d.ts +12 -0
- package/dist-public/src/discoveryTeams.js +516 -0
- package/dist-public/src/discoveryZoom.d.ts +12 -0
- package/dist-public/src/discoveryZoom.js +523 -0
- package/dist-public/src/elicitationSurface.d.ts +13 -0
- package/dist-public/src/elicitationSurface.js +77 -0
- package/dist-public/src/errorReport.d.ts +99 -0
- package/dist-public/src/errorReport.js +443 -0
- package/dist-public/src/errorTaxonomy.d.ts +84 -0
- package/dist-public/src/errorTaxonomy.js +189 -0
- package/dist-public/src/evalCalibration.d.ts +82 -0
- package/dist-public/src/evalCalibration.js +169 -0
- package/dist-public/src/evalChecks.d.ts +21 -0
- package/dist-public/src/evalChecks.js +295 -0
- package/dist-public/src/evalCompile.d.ts +56 -0
- package/dist-public/src/evalCompile.js +58 -0
- package/dist-public/src/evalImprove.d.ts +60 -0
- package/dist-public/src/evalImprove.js +175 -0
- package/dist-public/src/evalJudge.d.ts +47 -0
- package/dist-public/src/evalJudge.js +143 -0
- package/dist-public/src/evalLabels.d.ts +100 -0
- package/dist-public/src/evalLabels.js +287 -0
- package/dist-public/src/evalRecord.d.ts +68 -0
- package/dist-public/src/evalRecord.js +165 -0
- package/dist-public/src/evalRoast.d.ts +88 -0
- package/dist-public/src/evalRoast.js +249 -0
- package/dist-public/src/evidenceIntake.d.ts +66 -0
- package/dist-public/src/evidenceIntake.js +356 -0
- package/dist-public/src/feedback.d.ts +78 -0
- package/dist-public/src/feedback.js +294 -0
- package/dist-public/src/firefliesClient.d.ts +106 -0
- package/dist-public/src/firefliesClient.js +258 -0
- package/dist-public/src/firstMoveTensions.d.ts +10 -0
- package/dist-public/src/firstMoveTensions.js +93 -0
- package/dist-public/src/gitRun.d.ts +21 -0
- package/dist-public/src/gitRun.js +50 -0
- package/dist-public/src/githubReconcile.d.ts +94 -0
- package/dist-public/src/githubReconcile.js +205 -0
- package/dist-public/src/gmailNango.d.ts +131 -0
- package/dist-public/src/gmailNango.js +329 -0
- package/dist-public/src/gongNango.d.ts +118 -0
- package/dist-public/src/gongNango.js +308 -0
- package/dist-public/src/grammarGate.d.ts +13 -0
- package/dist-public/src/grammarGate.js +72 -0
- package/dist-public/src/harnessGates.d.ts +65 -0
- package/dist-public/src/harnessGates.js +168 -0
- package/dist-public/src/humanSurfaceEval.d.ts +19 -0
- package/dist-public/src/humanSurfaceEval.js +156 -0
- package/dist-public/src/ideate.d.ts +43 -0
- package/dist-public/src/ideate.js +255 -0
- package/dist-public/src/ideateContext.d.ts +11 -0
- package/dist-public/src/ideateContext.js +83 -0
- package/dist-public/src/index.d.ts +2 -0
- package/dist-public/src/index.js +4 -0
- package/dist-public/src/initCommand.d.ts +25 -0
- package/dist-public/src/initCommand.js +558 -0
- package/dist-public/src/interviewGate.d.ts +25 -0
- package/dist-public/src/interviewGate.js +126 -0
- package/dist-public/src/jsonFile.d.ts +2 -0
- package/dist-public/src/jsonFile.js +22 -0
- package/dist-public/src/loopBudget.d.ts +182 -0
- package/dist-public/src/loopBudget.js +494 -0
- package/dist-public/src/loopContracts.d.ts +35 -0
- package/dist-public/src/loopContracts.js +364 -0
- package/dist-public/src/machineState.d.ts +1 -0
- package/dist-public/src/machineState.js +9 -0
- package/dist-public/src/notionNango.d.ts +93 -0
- package/dist-public/src/notionNango.js +279 -0
- package/dist-public/src/orchestrationResult.d.ts +11 -0
- package/dist-public/src/orchestrationResult.js +73 -0
- package/dist-public/src/outlookNango.d.ts +124 -0
- package/dist-public/src/outlookNango.js +327 -0
- package/dist-public/src/packetCorrections.d.ts +40 -0
- package/dist-public/src/packetCorrections.js +172 -0
- package/dist-public/src/packetGlossary.d.ts +6 -0
- package/dist-public/src/packetGlossary.js +42 -0
- package/dist-public/src/packetIndex.d.ts +54 -0
- package/dist-public/src/packetIndex.js +744 -0
- package/dist-public/src/packetIndexEntry.d.ts +3 -0
- package/dist-public/src/packetIndexEntry.js +128 -0
- package/dist-public/src/packetIndexServe.d.ts +13 -0
- package/dist-public/src/packetIndexServe.js +113 -0
- package/dist-public/src/packetIndexWorker.d.ts +7 -0
- package/dist-public/src/packetIndexWorker.js +45 -0
- package/dist-public/src/packetLifecycle.d.ts +30 -0
- package/dist-public/src/packetLifecycle.js +127 -0
- package/dist-public/src/packetReconcile.d.ts +73 -0
- package/dist-public/src/packetReconcile.js +386 -0
- package/dist-public/src/packetStatus.d.ts +125 -0
- package/dist-public/src/packetStatus.js +770 -0
- package/dist-public/src/packetValidation.d.ts +17 -0
- package/dist-public/src/packetValidation.js +333 -0
- package/dist-public/src/packetVerify.d.ts +73 -0
- package/dist-public/src/packetVerify.js +303 -0
- package/dist-public/src/packetWrite.d.ts +52 -0
- package/dist-public/src/packetWrite.js +448 -0
- package/dist-public/src/pitch.d.ts +38 -0
- package/dist-public/src/pitch.js +154 -0
- package/dist-public/src/processMemo.d.ts +8 -0
- package/dist-public/src/processMemo.js +23 -0
- package/dist-public/src/productDetect.d.ts +30 -0
- package/dist-public/src/productDetect.js +376 -0
- package/dist-public/src/profile.d.ts +62 -0
- package/dist-public/src/profile.js +334 -0
- package/dist-public/src/questionModel.d.ts +46 -0
- package/dist-public/src/questionModel.js +74 -0
- package/dist-public/src/questionText.d.ts +7 -0
- package/dist-public/src/questionText.js +38 -0
- package/dist-public/src/redactConfig.d.ts +2 -0
- package/dist-public/src/redactConfig.js +11 -0
- package/dist-public/src/redactEngine.d.ts +59 -0
- package/dist-public/src/redactEngine.js +509 -0
- package/dist-public/src/redactGate.d.ts +63 -0
- package/dist-public/src/redactGate.js +209 -0
- package/dist-public/src/repoRead.d.ts +29 -0
- package/dist-public/src/repoRead.js +160 -0
- package/dist-public/src/research.d.ts +242 -0
- package/dist-public/src/research.js +1314 -0
- package/dist-public/src/researchCompletion.d.ts +34 -0
- package/dist-public/src/researchCompletion.js +123 -0
- package/dist-public/src/researchExecution.d.ts +47 -0
- package/dist-public/src/researchExecution.js +309 -0
- package/dist-public/src/researchFormat.d.ts +21 -0
- package/dist-public/src/researchFormat.js +77 -0
- package/dist-public/src/researchGate.d.ts +86 -0
- package/dist-public/src/researchGate.js +1036 -0
- package/dist-public/src/researchReceipt.d.ts +76 -0
- package/dist-public/src/researchReceipt.js +148 -0
- package/dist-public/src/researchRender.d.ts +2 -0
- package/dist-public/src/researchRender.js +267 -0
- package/dist-public/src/researchSigningKey.d.ts +19 -0
- package/dist-public/src/researchSigningKey.js +95 -0
- package/dist-public/src/riskClassify.d.ts +42 -0
- package/dist-public/src/riskClassify.js +149 -0
- package/dist-public/src/routines.d.ts +42 -0
- package/dist-public/src/routines.js +269 -0
- package/dist-public/src/routingPolicy.d.ts +172 -0
- package/dist-public/src/routingPolicy.js +646 -0
- package/dist-public/src/secretInput.d.ts +8 -0
- package/dist-public/src/secretInput.js +89 -0
- package/dist-public/src/selfCheck.d.ts +7 -0
- package/dist-public/src/selfCheck.js +473 -0
- package/dist-public/src/selfCheckCache.d.ts +29 -0
- package/dist-public/src/selfCheckCache.js +147 -0
- package/dist-public/src/severityClass.d.ts +15 -0
- package/dist-public/src/severityClass.js +22 -0
- package/dist-public/src/skillClientPolicy.d.ts +8 -0
- package/dist-public/src/skillClientPolicy.js +16 -0
- package/dist-public/src/skillLocal.d.ts +98 -0
- package/dist-public/src/skillLocal.js +463 -0
- package/dist-public/src/skillTreeDigest.d.ts +9 -0
- package/dist-public/src/skillTreeDigest.js +64 -0
- package/dist-public/src/slackNango.d.ts +62 -0
- package/dist-public/src/slackNango.js +208 -0
- package/dist-public/src/social/arxiv.d.ts +19 -0
- package/dist-public/src/social/arxiv.js +96 -0
- package/dist-public/src/social/github.d.ts +2 -0
- package/dist-public/src/social/github.js +78 -0
- package/dist-public/src/social/hackernews.d.ts +2 -0
- package/dist-public/src/social/hackernews.js +67 -0
- package/dist-public/src/social/index.d.ts +10 -0
- package/dist-public/src/social/index.js +79 -0
- package/dist-public/src/social/reddit.d.ts +2 -0
- package/dist-public/src/social/reddit.js +125 -0
- package/dist-public/src/social/types.d.ts +73 -0
- package/dist-public/src/social/types.js +61 -0
- package/dist-public/src/social/xml.d.ts +10 -0
- package/dist-public/src/social/xml.js +49 -0
- package/dist-public/src/social/youtube.d.ts +7 -0
- package/dist-public/src/social/youtube.js +217 -0
- package/dist-public/src/sourceIngress.d.ts +488 -0
- package/dist-public/src/sourceIngress.js +1651 -0
- package/dist-public/src/specAfter.d.ts +187 -0
- package/dist-public/src/specAfter.js +814 -0
- package/dist-public/src/specBudget.d.ts +124 -0
- package/dist-public/src/specBudget.js +424 -0
- package/dist-public/src/specDecisionSignals.d.ts +38 -0
- package/dist-public/src/specDecisionSignals.js +121 -0
- package/dist-public/src/specLinkedCommits.d.ts +7 -0
- package/dist-public/src/specLinkedCommits.js +107 -0
- package/dist-public/src/specSections.d.ts +105 -0
- package/dist-public/src/specSections.js +718 -0
- package/dist-public/src/statusGlyphs.d.ts +18 -0
- package/dist-public/src/statusGlyphs.js +75 -0
- package/dist-public/src/swarmCommand.d.ts +10 -0
- package/dist-public/src/swarmCommand.js +96 -0
- package/dist-public/src/teamsNango.d.ts +114 -0
- package/dist-public/src/teamsNango.js +301 -0
- package/dist-public/src/tokenStore.d.ts +10 -0
- package/dist-public/src/tokenStore.js +77 -0
- package/dist-public/src/trustEnvelope.d.ts +78 -0
- package/dist-public/src/trustEnvelope.js +392 -0
- package/dist-public/src/untrustedText.d.ts +6 -0
- package/dist-public/src/untrustedText.js +20 -0
- package/dist-public/src/updateNotice.d.ts +41 -0
- package/dist-public/src/updateNotice.js +290 -0
- package/dist-public/src/vendorYaml.d.ts +1 -0
- package/dist-public/src/vendorYaml.js +7374 -0
- package/dist-public/src/workflowRunActuals.d.ts +67 -0
- package/dist-public/src/workflowRunActuals.js +184 -0
- package/dist-public/src/zendeskDiscovery.d.ts +12 -0
- package/dist-public/src/zendeskDiscovery.js +513 -0
- package/dist-public/src/zendeskNango.d.ts +131 -0
- package/dist-public/src/zendeskNango.js +344 -0
- package/dist-public/src/zoomNango.d.ts +106 -0
- package/dist-public/src/zoomNango.js +351 -0
- package/docs/CHANGELOG.md +32 -0
- package/docs/THIRD_PARTY_NOTICES.md +36 -0
- package/package.json +71 -4
- package/schemas/bug-capsule-receipt.schema.json +54 -0
- package/schemas/bug-capsule.schema.json +189 -0
- package/schemas/discovery-evidence-envelope.schema.json +79 -0
- package/schemas/discovery-processing-receipt.schema.json +71 -0
- package/schemas/discovery-service-contract.schema.json +189 -0
- package/skills/AGENTS.md +32 -0
- package/skills/README.md +287 -0
- package/skills/bug/SKILL.md +49 -0
- package/skills/build-preview-spec/SKILL.md +103 -0
- package/skills/capture-external-artifact/SKILL.md +23 -0
- package/skills/capture-external-artifact/agents/openai.yaml +4 -0
- package/skills/capture-external-artifact/references/extractor-libraries.md +27 -0
- package/skills/check-spec-health/SKILL.md +45 -0
- package/skills/check-spec-health/agents/openai.yaml +4 -0
- package/skills/competitive-positioning/SKILL.md +86 -0
- package/skills/competitive-positioning/agents/openai.yaml +4 -0
- package/skills/cpo-lens/SKILL.md +398 -0
- package/skills/cpo-lens/agents/openai.yaml +4 -0
- package/skills/create-prd/SKILL.md +26 -0
- package/skills/create-prd/agents/openai.yaml +4 -0
- package/skills/customer-discovery/SKILL.md +192 -0
- package/skills/design-system/SKILL.md +49 -0
- package/skills/design-system/agents/openai.yaml +4 -0
- package/skills/discussion-guide/SKILL.md +75 -0
- package/skills/discussion-guide/agents/openai.yaml +4 -0
- package/skills/firecrawl-research-papers/SKILL.md +96 -0
- package/skills/firecrawl-research-papers/agents/openai.yaml +4 -0
- package/skills/foo-roast/SKILL.md +325 -0
- package/skills/generate-gtm-brief/SKILL.md +41 -0
- package/skills/generate-gtm-brief/agents/openai.yaml +4 -0
- package/skills/generate-gtm-brief/references/gtm-brief-template.md +56 -0
- package/skills/gong-quotes/SKILL.md +43 -0
- package/skills/gong-quotes/agents/openai.yaml +4 -0
- package/skills/grill-me/SKILL.md +27 -0
- package/skills/grill-me/agents/openai.yaml +4 -0
- package/skills/ideate/SKILL.md +180 -0
- package/skills/ideate/references/family-packs.md +5 -0
- package/skills/initiative-tracker/SKILL.md +23 -0
- package/skills/initiative-tracker/agents/openai.yaml +4 -0
- package/skills/interop-review/SKILL.md +25 -0
- package/skills/interop-review/agents/openai.yaml +4 -0
- package/skills/interview-me/SKILL.md +404 -0
- package/skills/interview-me/agents/openai.yaml +4 -0
- package/skills/loop-library-audit/SKILL.md +123 -0
- package/skills/pitch/SKILL.md +110 -0
- package/skills/pitch/references/opportunity-assessment.md +136 -0
- package/skills/pitch/references/prfaq-template.md +54 -0
- package/skills/pmm-release-briefing/SKILL.md +27 -0
- package/skills/pmm-release-briefing/agents/openai.yaml +4 -0
- package/skills/pmm-release-briefing/references/variant-generalized.md +16 -0
- package/skills/positioning-messaging/SKILL.md +70 -0
- package/skills/positioning-messaging/agents/openai.yaml +4 -0
- package/skills/positioning-messaging/references/guest-insights.md +1400 -0
- package/skills/preview-swarm/SKILL.md +418 -0
- package/skills/preview-swarm/agents/openai.yaml +4 -0
- package/skills/preview-swarm/references/html-effectiveness-build-previews.md +168 -0
- package/skills/product-copywriting/SKILL.md +127 -0
- package/skills/product-copywriting/agents/openai.yaml +4 -0
- package/skills/product-copywriting/references/foo-voice.md +26 -0
- package/skills/product-shape-interview/SKILL.md +219 -0
- package/skills/product-shape-interview/agents/openai.yaml +4 -0
- package/skills/ready-for-release/SKILL.md +39 -0
- package/skills/ready-for-release/agents/openai.yaml +4 -0
- package/skills/redact-transcripts/SKILL.md +23 -0
- package/skills/redact-transcripts/agents/openai.yaml +4 -0
- package/skills/research-brief/SKILL.md +48 -0
- package/skills/research-brief/agents/openai.yaml +4 -0
- package/skills/research-refresh/SKILL.md +63 -0
- package/skills/research-refresh/references/worked-cases.md +44 -0
- package/skills/review-loop/SKILL.md +200 -0
- package/skills/review-spec/SKILL.md +32 -0
- package/skills/review-spec/agents/openai.yaml +4 -0
- package/skills/rfc-from-research/SKILL.md +42 -0
- package/skills/rfc-from-research/agents/openai.yaml +4 -0
- package/skills/rfc-from-research/references/rfc-pattern.md +69 -0
- package/skills/skill-registry.yaml +810 -0
- package/skills/spec-cleanup/SKILL.md +103 -0
- package/skills/spec-cleanup/agents/openai.yaml +4 -0
- package/skills/spec-swarm/SKILL.md +87 -0
- package/skills/spec-swarm/agents/openai.yaml +4 -0
- package/skills/spec-swarm/template/SKILL.template.md +94 -0
- package/skills/spec-swarm/template/personas/accessibility-inclusion.md +40 -0
- package/skills/spec-swarm/template/personas/ai-technical-pm.md +69 -0
- package/skills/spec-swarm/template/personas/analytics-engineering.md +39 -0
- package/skills/spec-swarm/template/personas/applied-ai-eval.md +64 -0
- package/skills/spec-swarm/template/personas/business-gm-pm.md +67 -0
- package/skills/spec-swarm/template/personas/consumer-craft-pm.md +68 -0
- package/skills/spec-swarm/template/personas/content-design.md +40 -0
- package/skills/spec-swarm/template/personas/cpo.md +42 -0
- package/skills/spec-swarm/template/personas/data-science.md +42 -0
- package/skills/spec-swarm/template/personas/developer-experience.md +65 -0
- package/skills/spec-swarm/template/personas/dx-product.md +70 -0
- package/skills/spec-swarm/template/personas/field.md +43 -0
- package/skills/spec-swarm/template/personas/finance-cfo.md +40 -0
- package/skills/spec-swarm/template/personas/growth-pm.md +67 -0
- package/skills/spec-swarm/template/personas/platform-pm.md +67 -0
- package/skills/spec-swarm/template/personas/pmm.md +43 -0
- package/skills/spec-swarm/template/personas/principal-product-designer.md +42 -0
- package/skills/spec-swarm/template/personas/product-ops-program.md +41 -0
- package/skills/spec-swarm/template/personas/qa-release.md +41 -0
- package/skills/spec-swarm/template/personas/responsible-ai-safety.md +64 -0
- package/skills/spec-swarm/template/personas/security-privacy-legal.md +40 -0
- package/skills/spec-swarm/template/personas/strategy-competitive.md +41 -0
- package/skills/spec-swarm/template/personas/technical-architect.md +42 -0
- package/skills/spec-swarm/template/personas/technical-lead.md +43 -0
- package/skills/spec-swarm/template/personas/user-research.md +41 -0
- package/skills/spec-swarm-accessibility-inclusion/SKILL.md +95 -0
- package/skills/spec-swarm-accessibility-inclusion/agents/openai.yaml +4 -0
- package/skills/spec-swarm-ai-technical-pm/SKILL.md +124 -0
- package/skills/spec-swarm-analytics-engineering/SKILL.md +94 -0
- package/skills/spec-swarm-analytics-engineering/agents/openai.yaml +4 -0
- package/skills/spec-swarm-applied-ai-eval/SKILL.md +120 -0
- package/skills/spec-swarm-business-gm-pm/SKILL.md +122 -0
- package/skills/spec-swarm-consumer-craft-pm/SKILL.md +122 -0
- package/skills/spec-swarm-content-design/SKILL.md +95 -0
- package/skills/spec-swarm-content-design/agents/openai.yaml +4 -0
- package/skills/spec-swarm-cpo/SKILL.md +94 -0
- package/skills/spec-swarm-cpo/agents/openai.yaml +4 -0
- package/skills/spec-swarm-data-science/SKILL.md +95 -0
- package/skills/spec-swarm-data-science/agents/openai.yaml +4 -0
- package/skills/spec-swarm-developer-experience/SKILL.md +121 -0
- package/skills/spec-swarm-dx-product/SKILL.md +126 -0
- package/skills/spec-swarm-field/SKILL.md +96 -0
- package/skills/spec-swarm-field/agents/openai.yaml +4 -0
- package/skills/spec-swarm-finance-cfo/SKILL.md +95 -0
- package/skills/spec-swarm-finance-cfo/agents/openai.yaml +4 -0
- package/skills/spec-swarm-growth-pm/SKILL.md +122 -0
- package/skills/spec-swarm-platform-pm/SKILL.md +122 -0
- package/skills/spec-swarm-pmm/SKILL.md +96 -0
- package/skills/spec-swarm-pmm/agents/openai.yaml +4 -0
- package/skills/spec-swarm-principal-product-designer/SKILL.md +95 -0
- package/skills/spec-swarm-principal-product-designer/agents/openai.yaml +4 -0
- package/skills/spec-swarm-product-ops-program/SKILL.md +96 -0
- package/skills/spec-swarm-product-ops-program/agents/openai.yaml +4 -0
- package/skills/spec-swarm-qa-release/SKILL.md +96 -0
- package/skills/spec-swarm-qa-release/agents/openai.yaml +4 -0
- package/skills/spec-swarm-responsible-ai-safety/SKILL.md +120 -0
- package/skills/spec-swarm-security-privacy-legal/SKILL.md +95 -0
- package/skills/spec-swarm-security-privacy-legal/agents/openai.yaml +4 -0
- package/skills/spec-swarm-strategy-competitive/SKILL.md +96 -0
- package/skills/spec-swarm-strategy-competitive/agents/openai.yaml +4 -0
- package/skills/spec-swarm-technical-architect/SKILL.md +95 -0
- package/skills/spec-swarm-technical-architect/agents/openai.yaml +4 -0
- package/skills/spec-swarm-technical-lead/SKILL.md +96 -0
- package/skills/spec-swarm-technical-lead/agents/openai.yaml +4 -0
- package/skills/spec-swarm-user-research/SKILL.md +95 -0
- package/skills/spec-swarm-user-research/agents/openai.yaml +4 -0
- package/skills/strategy-check/SKILL.md +170 -0
- package/skills/strategy-check/agents/openai.yaml +4 -0
- package/skills/study-digest/SKILL.md +41 -0
- package/skills/synthetic-customer/SKILL.md +68 -0
- package/skills/update-cli-spec/SKILL.md +69 -0
- package/skills/update-cli-spec/agents/openai.yaml +4 -0
- package/skills/voc-researcher/SKILL.md +45 -0
- package/skills/voc-researcher/agents/openai.yaml +4 -0
- package/skills-lock.json +35 -0
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
// Shared, runtime-neutral reconcile engine (asp-cli-lifecycle-v0 T-001).
|
|
2
|
+
//
|
|
3
|
+
// Reconcile answers one question: does every changed file map to an agreed task
|
|
4
|
+
// touchpoint? The per-packet `reconcile.ts` modules used to each carry an
|
|
5
|
+
// identical copy of this logic, differing only by a human task noun and the
|
|
6
|
+
// spec_id/packet labels — both of which are derivable from the packet itself.
|
|
7
|
+
// This module is that single copy; the per-packet wrappers now delegate here,
|
|
8
|
+
// and `foo asp reconcile` can run it generically on any packet dir with no
|
|
9
|
+
// compiled per-packet module at all (T-002).
|
|
10
|
+
//
|
|
11
|
+
// The richer worked example (examples/calpal-scheduling) keeps its own bespoke
|
|
12
|
+
// reconcile — freshness, drift, and work-evidence findings — and is not folded
|
|
13
|
+
// into this engine.
|
|
14
|
+
import { gitRun } from "./gitRun.js";
|
|
15
|
+
import { readFileSync } from "node:fs";
|
|
16
|
+
import path from "node:path";
|
|
17
|
+
import { parse as parseYaml } from "./vendorYaml.js";
|
|
18
|
+
import { approvalStates, jiraScopeCoversIssue, jiraScopeString, jiraSiteHost, parseJiraScope, parseJiraScopeString, parseJiraSource, sourceKey, } from "./sourceIngress.js";
|
|
19
|
+
import { UsageError } from "./errorTaxonomy.js";
|
|
20
|
+
function asObject(value) {
|
|
21
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
22
|
+
}
|
|
23
|
+
export function parseReconcileArgs(args) {
|
|
24
|
+
const options = { changedFiles: [], gitDiff: false };
|
|
25
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
26
|
+
const arg = args[index];
|
|
27
|
+
if (arg === "--changed-file") {
|
|
28
|
+
const value = args[index + 1];
|
|
29
|
+
if (!value)
|
|
30
|
+
throw new Error("--changed-file requires a value");
|
|
31
|
+
options.changedFiles.push(value);
|
|
32
|
+
index += 1;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (arg === "--git-diff") {
|
|
36
|
+
options.gitDiff = true;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (arg === "--jira-evidence") {
|
|
40
|
+
const value = args[index + 1];
|
|
41
|
+
if (!value)
|
|
42
|
+
throw new Error("--jira-evidence requires a path to a Jira evidence fixture (JSON)");
|
|
43
|
+
options.jiraEvidencePath = value;
|
|
44
|
+
index += 1;
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
throw new Error(`unknown reconcile argument: ${arg}`);
|
|
48
|
+
}
|
|
49
|
+
return options;
|
|
50
|
+
}
|
|
51
|
+
function touchMatches(touch, changedFile) {
|
|
52
|
+
return touch.endsWith("/") ? changedFile.startsWith(touch) : changedFile === touch;
|
|
53
|
+
}
|
|
54
|
+
// What the working tree changed, as the drift check must see it.
|
|
55
|
+
//
|
|
56
|
+
// This was `git diff --name-only`, which answers a much narrower question than
|
|
57
|
+
// anyone reading the call site assumed: *unstaged* edits to *tracked* files. It
|
|
58
|
+
// therefore had two blind spots, and drift silently reported success on work it
|
|
59
|
+
// had never seen — the exact "claimed read as proven" failure foo exists to stop.
|
|
60
|
+
//
|
|
61
|
+
// 1. New files were invisible. `git diff` cannot see an untracked file at any
|
|
62
|
+
// --cached setting. A build made entirely of new files — the common agent
|
|
63
|
+
// case — reconciled perfectly clean.
|
|
64
|
+
// 2. Staged files were invisible, including *modified tracked* ones. So after
|
|
65
|
+
// a routine `git add -A` the check saw NOTHING AT ALL and called the packet
|
|
66
|
+
// clean. Staging your work disabled the drift detector.
|
|
67
|
+
//
|
|
68
|
+
// Both halves are needed and neither subsumes the other: `diff HEAD` covers
|
|
69
|
+
// staged+unstaged for files git tracks, `ls-files --others` covers files git has
|
|
70
|
+
// never seen. --exclude-standard keeps .gitignore'd paths (node_modules, build
|
|
71
|
+
// output) out, so the report stays about the author's work.
|
|
72
|
+
export function gitChangedFiles(root) {
|
|
73
|
+
const tracked = gitRun(["-C", root, "diff", "--name-only", headRef(root)]);
|
|
74
|
+
if (!tracked.ok)
|
|
75
|
+
throw new Error(tracked.message);
|
|
76
|
+
const untracked = gitRun(["-C", root, "ls-files", "--others", "--exclude-standard"]);
|
|
77
|
+
if (!untracked.ok)
|
|
78
|
+
throw new Error(untracked.message);
|
|
79
|
+
const lines = [...splitGitLines(tracked.stdout), ...splitGitLines(untracked.stdout)];
|
|
80
|
+
// A file can be both staged and dirty; it is still one changed file.
|
|
81
|
+
return [...new Set(lines)].sort();
|
|
82
|
+
}
|
|
83
|
+
// `diff HEAD` is the right comparison once there is a commit to compare against.
|
|
84
|
+
// In a repo whose first commit has not landed, HEAD does not resolve and git
|
|
85
|
+
// exits non-zero — so the reconcile of a brand-new packet would crash rather
|
|
86
|
+
// than report. There, everything in the index is new, and `--cached` alone says so.
|
|
87
|
+
function headRef(root) {
|
|
88
|
+
const head = gitRun(["-C", root, "rev-parse", "--verify", "HEAD"], { stdio: ["ignore", "pipe", "ignore"] });
|
|
89
|
+
return head.ok ? "HEAD" : "--cached";
|
|
90
|
+
}
|
|
91
|
+
function splitGitLines(stdout) {
|
|
92
|
+
return stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
93
|
+
}
|
|
94
|
+
function tasksForChangedFile(tasks, changedFile) {
|
|
95
|
+
return tasks.filter((task) => (task.touches ?? []).some((touch) => touchMatches(touch, changedFile)));
|
|
96
|
+
}
|
|
97
|
+
// The COVERAGE-axis core (reconcile-anywhere-v0 T-001): classify each changed
|
|
98
|
+
// file against the agreed task touchpoints and emit the unmapped findings. Pure
|
|
99
|
+
// and packet-free — the shared engine the packet path (`reconcilePacket`, below)
|
|
100
|
+
// and the top-level packet-free `foo reconcile` both call, so the two entry
|
|
101
|
+
// points can never drift (D-001). With no tasks (a repo that has never heard of
|
|
102
|
+
// packets), every changed file classifies `unmapped`, which IS the honest
|
|
103
|
+
// adoption signal: nothing is covered by an agreed task yet.
|
|
104
|
+
export function classifyChangedFiles(tasks, changedFileInputs, noun = "") {
|
|
105
|
+
const findings = [];
|
|
106
|
+
const nounPrefix = noun ? `${noun} ` : "";
|
|
107
|
+
const changed_files = [...new Set(changedFileInputs)].sort().map((changedFile) => {
|
|
108
|
+
const mappedTasks = tasksForChangedFile(tasks, changedFile);
|
|
109
|
+
const agreements = Object.fromEntries(mappedTasks.map((task) => [task.id, task.agreement]));
|
|
110
|
+
const state = mappedTasks.length === 0
|
|
111
|
+
? "unmapped"
|
|
112
|
+
: Object.values(agreements).includes("agreed")
|
|
113
|
+
? "agreed"
|
|
114
|
+
: "unagreed";
|
|
115
|
+
if (state === "unmapped") {
|
|
116
|
+
findings.push({
|
|
117
|
+
kind: "unmapped_changed_file",
|
|
118
|
+
severity: "high",
|
|
119
|
+
file: changedFile,
|
|
120
|
+
subject: `file:${changedFile}`,
|
|
121
|
+
summary: `Changed file does not map to any agreed ${nounPrefix}task touchpoint.`,
|
|
122
|
+
suggested_actions: [
|
|
123
|
+
"map the file to an agreed task",
|
|
124
|
+
"create a discovered task",
|
|
125
|
+
"revert the unrelated file change",
|
|
126
|
+
],
|
|
127
|
+
requires_human: true,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
path: changedFile,
|
|
132
|
+
state,
|
|
133
|
+
mapped_tasks: mappedTasks.map((task) => task.id),
|
|
134
|
+
mapped_task_agreements: agreements,
|
|
135
|
+
};
|
|
136
|
+
});
|
|
137
|
+
return { changed_files, findings };
|
|
138
|
+
}
|
|
139
|
+
// Jira status names are site-configurable, so done detection matches a small
|
|
140
|
+
// documented name set and findings report the status name they saw — the
|
|
141
|
+
// engine never pretends to know a site's workflow.
|
|
142
|
+
const JIRA_DONE_STATUS = /^(done|closed|resolved)$/i;
|
|
143
|
+
// Freshness is DERIVED from observed timestamps (R-006): an issue untouched
|
|
144
|
+
// for this many days before the observation is reported stale.
|
|
145
|
+
export const JIRA_STALE_DAYS = 30;
|
|
146
|
+
function jiraTrackerDone(status) {
|
|
147
|
+
return JIRA_DONE_STATUS.test(status.trim());
|
|
148
|
+
}
|
|
149
|
+
function jiraFreshness(updated, observedAt) {
|
|
150
|
+
const ageDays = Math.floor((Date.parse(observedAt) - Date.parse(updated)) / 86_400_000);
|
|
151
|
+
return { freshness: ageDays > JIRA_STALE_DAYS ? "stale" : "fresh", age_days: ageDays };
|
|
152
|
+
}
|
|
153
|
+
// Reconcile a validated Jira evidence fixture against packet task state.
|
|
154
|
+
// Pure apart from reading the packet's approval ledger: the gate refuses
|
|
155
|
+
// unapproved sources (exit-path, like the GitHub reconcile gate), and evidence
|
|
156
|
+
// that falls outside the approved scope or cannot be mapped is EXCLUDED with a
|
|
157
|
+
// finding — never admitted, never resolved.
|
|
158
|
+
export function jiraWorkSystemReconcile(opts) {
|
|
159
|
+
if (opts.fixture.provider !== "jira") {
|
|
160
|
+
throw new UsageError(`jira evidence fixture must declare provider "jira"`, "E_BAD_FLAG");
|
|
161
|
+
}
|
|
162
|
+
if (typeof opts.fixture.observed_at !== "string" || Number.isNaN(Date.parse(opts.fixture.observed_at))) {
|
|
163
|
+
throw new UsageError(`jira evidence fixture needs an ISO observed_at — freshness is derived from observed timestamps (R-006)`, "E_BAD_FLAG");
|
|
164
|
+
}
|
|
165
|
+
const site = jiraSiteHost(opts.fixture.site);
|
|
166
|
+
const sourceId = { ingress_path: "nango", provider: "jira", connection_id: site };
|
|
167
|
+
const scope = typeof opts.fixture.scope === "string" ? parseJiraScopeString(opts.fixture.scope) : parseJiraScope(opts.fixture.scope);
|
|
168
|
+
const scopeStr = jiraScopeString(scope);
|
|
169
|
+
// Gate (R-004): connection is not approval — the source must be approved for
|
|
170
|
+
// THIS packet and the read must have run through exactly an approved scope
|
|
171
|
+
// (substrate accumulation is exact-match; nothing here widens it).
|
|
172
|
+
const approval = approvalStates(opts.packetDir).get(sourceKey(sourceId));
|
|
173
|
+
if (approval?.state !== "approved" || !approval.scopes.includes(scopeStr)) {
|
|
174
|
+
const rel = path.relative(process.cwd(), opts.packetDir).split(path.sep).join("/") || opts.packetDir;
|
|
175
|
+
throw new Error(`Jira source ${site} is ${approval?.state ?? "excluded"} for this packet, or the declared scope was never approved — connection is not approval.\n` +
|
|
176
|
+
`Approve the bounded scope, then re-run:\n` +
|
|
177
|
+
` foo source approve ${rel} --provider jira --connection ${site} --scope '${scopeStr}' --by <you>\n`);
|
|
178
|
+
}
|
|
179
|
+
const byTask = new Map(opts.tasks.map((task) => [task.id, task]));
|
|
180
|
+
const findings = [];
|
|
181
|
+
const task_conclusions = [];
|
|
182
|
+
let admitted = 0;
|
|
183
|
+
let excluded = 0;
|
|
184
|
+
for (const entry of opts.fixture.issues ?? []) {
|
|
185
|
+
let issue;
|
|
186
|
+
try {
|
|
187
|
+
issue = parseJiraSource(entry?.issue);
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
excluded += 1;
|
|
191
|
+
findings.push({
|
|
192
|
+
kind: "work_system_unparseable",
|
|
193
|
+
evidence_kind: "work_system",
|
|
194
|
+
severity: "high",
|
|
195
|
+
summary: `a Jira issue fixture was refused by the parse layer: ${error instanceof Error ? error.message : String(error)}`,
|
|
196
|
+
requires_human: true,
|
|
197
|
+
});
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
// Scope containment (R-004): an issue outside the approved scope never
|
|
201
|
+
// surfaces — reported loudly, not silently dropped.
|
|
202
|
+
if (!jiraScopeCoversIssue(scope, issue)) {
|
|
203
|
+
excluded += 1;
|
|
204
|
+
findings.push({
|
|
205
|
+
kind: "work_system_out_of_scope",
|
|
206
|
+
evidence_kind: "work_system",
|
|
207
|
+
severity: "high",
|
|
208
|
+
issue_key: issue.key,
|
|
209
|
+
summary: `issue ${issue.key} falls outside the approved scope — the runtime read an unapproved project`,
|
|
210
|
+
requires_human: true,
|
|
211
|
+
});
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
admitted += 1;
|
|
215
|
+
const freshness = jiraFreshness(issue.updated, opts.fixture.observed_at);
|
|
216
|
+
if (freshness.freshness === "stale") {
|
|
217
|
+
findings.push({
|
|
218
|
+
kind: "work_system_stale",
|
|
219
|
+
evidence_kind: "work_system",
|
|
220
|
+
severity: "medium",
|
|
221
|
+
issue_key: issue.key,
|
|
222
|
+
freshness,
|
|
223
|
+
summary: `issue ${issue.key} was last updated ${freshness.age_days} days before observation — freshness is derived from observed timestamps, not asserted`,
|
|
224
|
+
requires_human: false,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
const cites = typeof entry.cites_task === "string" ? entry.cites_task.trim() : "";
|
|
228
|
+
if (!cites) {
|
|
229
|
+
findings.push({
|
|
230
|
+
kind: "work_system_unmapped",
|
|
231
|
+
evidence_kind: "work_system",
|
|
232
|
+
severity: "medium",
|
|
233
|
+
issue_key: issue.key,
|
|
234
|
+
status: issue.status,
|
|
235
|
+
summary: `issue ${issue.key} cites no packet task — work-system evidence maps onto tasks only by explicit citation, never by guessing`,
|
|
236
|
+
requires_human: true,
|
|
237
|
+
});
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
const task = byTask.get(cites);
|
|
241
|
+
if (!task) {
|
|
242
|
+
findings.push({
|
|
243
|
+
kind: "work_system_unknown_task",
|
|
244
|
+
evidence_kind: "work_system",
|
|
245
|
+
severity: "medium",
|
|
246
|
+
issue_key: issue.key,
|
|
247
|
+
cites_task: cites,
|
|
248
|
+
summary: `issue ${issue.key} cites task ${cites}, which this packet does not define`,
|
|
249
|
+
requires_human: true,
|
|
250
|
+
});
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
const trackerDone = jiraTrackerDone(issue.status);
|
|
254
|
+
const packetDone = task.status === "done";
|
|
255
|
+
if (trackerDone && !packetDone) {
|
|
256
|
+
findings.push({
|
|
257
|
+
kind: "work_system_conflict",
|
|
258
|
+
evidence_kind: "work_system",
|
|
259
|
+
severity: "high",
|
|
260
|
+
issue_key: issue.key,
|
|
261
|
+
cites_task: cites,
|
|
262
|
+
tracker_status: issue.status,
|
|
263
|
+
packet_status: task.status,
|
|
264
|
+
summary: `tracker says ${issue.key} is done (${issue.status}) but packet task ${cites} is not — reported, never silently resolved (R-006)`,
|
|
265
|
+
requires_human: true,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
else if (!trackerDone && packetDone) {
|
|
269
|
+
findings.push({
|
|
270
|
+
kind: "work_system_conflict",
|
|
271
|
+
evidence_kind: "work_system",
|
|
272
|
+
severity: "high",
|
|
273
|
+
issue_key: issue.key,
|
|
274
|
+
cites_task: cites,
|
|
275
|
+
tracker_status: issue.status,
|
|
276
|
+
packet_status: "done",
|
|
277
|
+
summary: `packet task ${cites} is done but tracker shows ${issue.key} as ${issue.status} — reported, never silently resolved (R-006)`,
|
|
278
|
+
requires_human: true,
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
findings.push({
|
|
283
|
+
kind: "work_system_status",
|
|
284
|
+
evidence_kind: "work_system",
|
|
285
|
+
severity: "low",
|
|
286
|
+
issue_key: issue.key,
|
|
287
|
+
cites_task: cites,
|
|
288
|
+
tracker_status: issue.status,
|
|
289
|
+
freshness,
|
|
290
|
+
summary: `issue ${issue.key} (${issue.status}) vs task ${cites} (${packetDone ? "done" : "not done"})`,
|
|
291
|
+
requires_human: false,
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
// RISK-001: tracker status creates false certainty when repo proof is
|
|
295
|
+
// missing. A done-category issue with no remote links is the exact
|
|
296
|
+
// conflict class — rendered, never resolved.
|
|
297
|
+
if (trackerDone && (issue.remote_links ?? []).length === 0) {
|
|
298
|
+
findings.push({
|
|
299
|
+
kind: "work_system_missing_proof",
|
|
300
|
+
evidence_kind: "work_system",
|
|
301
|
+
severity: "high",
|
|
302
|
+
issue_key: issue.key,
|
|
303
|
+
cites_task: cites,
|
|
304
|
+
summary: `tracker says ${issue.key} is done with no remote links to repo proof — tracker status alone proves nothing (RISK-001)`,
|
|
305
|
+
requires_human: true,
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
// The engine's own derived verdict — labeled agent_inference so it is
|
|
309
|
+
// never mistaken for tracker or repo fact (V-006).
|
|
310
|
+
task_conclusions.push({
|
|
311
|
+
task_id: cites,
|
|
312
|
+
issue_key: issue.key,
|
|
313
|
+
packet_status: packetDone ? "done" : "not done",
|
|
314
|
+
tracker_status: issue.status,
|
|
315
|
+
tracker_done_category: trackerDone,
|
|
316
|
+
conclusion: trackerDone && packetDone ? "corroborated" : trackerDone || packetDone ? "conflict" : "in_flight",
|
|
317
|
+
basis: "deterministic name-match of tracker status against packet task state; statuses are site-configurable names",
|
|
318
|
+
evidence_kind: "agent_inference",
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
return {
|
|
322
|
+
source_id: sourceId,
|
|
323
|
+
site,
|
|
324
|
+
observed_at: opts.fixture.observed_at,
|
|
325
|
+
scope: scopeStr,
|
|
326
|
+
admitted,
|
|
327
|
+
excluded,
|
|
328
|
+
findings,
|
|
329
|
+
task_conclusions,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
// Reads a Jira evidence fixture file for reconcile. The fixture path is
|
|
333
|
+
// resolved against the repo root, like every other fixture flag.
|
|
334
|
+
export function readJiraEvidenceFixture(root, fixturePath) {
|
|
335
|
+
const resolved = path.resolve(root, fixturePath);
|
|
336
|
+
let parsed;
|
|
337
|
+
try {
|
|
338
|
+
parsed = JSON.parse(readFileSync(resolved, "utf8"));
|
|
339
|
+
}
|
|
340
|
+
catch {
|
|
341
|
+
throw new UsageError(`--jira-evidence is not readable JSON: ${fixturePath}`, "E_BAD_FLAG");
|
|
342
|
+
}
|
|
343
|
+
const fixture = parsed;
|
|
344
|
+
if (!fixture || typeof fixture !== "object" || Array.isArray(fixture)) {
|
|
345
|
+
throw new UsageError(`--jira-evidence must be a JSON object`, "E_BAD_FLAG");
|
|
346
|
+
}
|
|
347
|
+
if (fixture.provider !== "jira" || typeof fixture.site !== "string" || !Array.isArray(fixture.issues)) {
|
|
348
|
+
throw new UsageError(`--jira-evidence needs {provider: "jira", site, observed_at, scope, issues}`, "E_BAD_FLAG");
|
|
349
|
+
}
|
|
350
|
+
return fixture;
|
|
351
|
+
}
|
|
352
|
+
export function reconcilePacket(options) {
|
|
353
|
+
const tasksDoc = asObject(parseYaml(readFileSync(path.join(options.packetDir, "tasks.yaml"), "utf8")));
|
|
354
|
+
const tasks = tasksDoc.tasks ?? [];
|
|
355
|
+
const gitDiff = options.gitDiff ?? false;
|
|
356
|
+
const requested = options.changedFiles ?? [];
|
|
357
|
+
const changedFileInputs = requested.length > 0 || !gitDiff ? requested : gitChangedFiles(options.root);
|
|
358
|
+
const noun = options.taskNoun ?? "";
|
|
359
|
+
const { changed_files: changedFiles, findings: repoFindings } = classifyChangedFiles(tasks, changedFileInputs, noun);
|
|
360
|
+
// Repo findings are labeled by evidence class so reconcile output
|
|
361
|
+
// distinguishes changed-file coverage from work-system evidence and agent
|
|
362
|
+
// inference (jira-source-connector-v0 T-005 / V-006).
|
|
363
|
+
const findings = repoFindings.map((f) => ({ ...f, evidence_kind: "repo" }));
|
|
364
|
+
let work_system;
|
|
365
|
+
if (options.jiraEvidencePath) {
|
|
366
|
+
const fixture = readJiraEvidenceFixture(options.root, options.jiraEvidencePath);
|
|
367
|
+
work_system = jiraWorkSystemReconcile({ packetDir: options.packetDir, fixture, tasks });
|
|
368
|
+
findings.push(...work_system.findings);
|
|
369
|
+
}
|
|
370
|
+
// packet is the packet dir relative to the repo root, in POSIX form, matching
|
|
371
|
+
// the literal value the per-packet wrappers used to hardcode.
|
|
372
|
+
const packet = path.relative(options.root, options.packetDir).split(path.sep).join("/");
|
|
373
|
+
const workSummary = work_system
|
|
374
|
+
? ` Work-system evidence from ${work_system.site}: ${work_system.admitted} admitted, ${work_system.excluded} excluded.`
|
|
375
|
+
: "";
|
|
376
|
+
return {
|
|
377
|
+
spec_id: tasksDoc.spec_id,
|
|
378
|
+
packet,
|
|
379
|
+
changed_files: changedFiles,
|
|
380
|
+
findings,
|
|
381
|
+
...(work_system ? { work_system } : {}),
|
|
382
|
+
summary: findings.length === 0
|
|
383
|
+
? `All changed files map to agreed ${noun ? `${noun} ` : ""}tasks.${workSummary}`
|
|
384
|
+
: `${findings.length} reconciliation finding(s) need review.${workSummary}`,
|
|
385
|
+
};
|
|
386
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { type DecisionFinding, type PacketDecisionRequest } from "./specSections.js";
|
|
2
|
+
export declare const PACKET_STATUS_SCHEMA_VERSION = "1.1";
|
|
3
|
+
export type TaskStatus = "todo" | "doing" | "blocked" | "done" | "dropped";
|
|
4
|
+
export type PacketNextAction = {
|
|
5
|
+
kind: "none";
|
|
6
|
+
reason: string;
|
|
7
|
+
} | {
|
|
8
|
+
kind: "reconcile";
|
|
9
|
+
reason: string;
|
|
10
|
+
} | {
|
|
11
|
+
kind: "decide";
|
|
12
|
+
decision: PacketDecisionRequest;
|
|
13
|
+
} | {
|
|
14
|
+
kind: "unblock";
|
|
15
|
+
task: {
|
|
16
|
+
id: string;
|
|
17
|
+
title: string;
|
|
18
|
+
reason: string | null;
|
|
19
|
+
};
|
|
20
|
+
} | {
|
|
21
|
+
kind: "task";
|
|
22
|
+
task: {
|
|
23
|
+
id: string;
|
|
24
|
+
title: string;
|
|
25
|
+
status: "todo" | "doing";
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
export interface PacketStatus {
|
|
29
|
+
packet: string;
|
|
30
|
+
spec_id: string;
|
|
31
|
+
title: string | null;
|
|
32
|
+
lifecycle: string | null;
|
|
33
|
+
lifecycle_stored: string | null;
|
|
34
|
+
lifecycle_effective: "done" | "in_flight";
|
|
35
|
+
lifecycle_drift: boolean;
|
|
36
|
+
stage: string | null;
|
|
37
|
+
mode: string | null;
|
|
38
|
+
tasks: {
|
|
39
|
+
total: number;
|
|
40
|
+
done: number;
|
|
41
|
+
doing: number;
|
|
42
|
+
blocked: number;
|
|
43
|
+
todo: number;
|
|
44
|
+
dropped: number;
|
|
45
|
+
};
|
|
46
|
+
proof: {
|
|
47
|
+
checks_total: number;
|
|
48
|
+
checks_done: number;
|
|
49
|
+
};
|
|
50
|
+
requirements: {
|
|
51
|
+
total: number;
|
|
52
|
+
covered: number;
|
|
53
|
+
};
|
|
54
|
+
requirement_priorities: Record<string, string>;
|
|
55
|
+
completed: string[];
|
|
56
|
+
task_list: Array<{
|
|
57
|
+
id: string;
|
|
58
|
+
title: string;
|
|
59
|
+
status: TaskStatus;
|
|
60
|
+
checksDone: number;
|
|
61
|
+
checksTotal: number;
|
|
62
|
+
agreement: string;
|
|
63
|
+
owner: string | null;
|
|
64
|
+
deps: string[];
|
|
65
|
+
refs: string[];
|
|
66
|
+
}>;
|
|
67
|
+
blocked: Array<{
|
|
68
|
+
id: string;
|
|
69
|
+
title: string;
|
|
70
|
+
reason: string | null;
|
|
71
|
+
}>;
|
|
72
|
+
stale: Array<{
|
|
73
|
+
id: string;
|
|
74
|
+
title: string;
|
|
75
|
+
agreement: string;
|
|
76
|
+
overdue: boolean;
|
|
77
|
+
}>;
|
|
78
|
+
open_questions: string[];
|
|
79
|
+
next_action: PacketNextAction;
|
|
80
|
+
decision_findings: DecisionFinding[];
|
|
81
|
+
next: {
|
|
82
|
+
id: string;
|
|
83
|
+
title: string;
|
|
84
|
+
kind: TaskStatus;
|
|
85
|
+
} | null;
|
|
86
|
+
drift: {
|
|
87
|
+
restamp: boolean;
|
|
88
|
+
};
|
|
89
|
+
verdict: {
|
|
90
|
+
state: string;
|
|
91
|
+
reason: string | null;
|
|
92
|
+
at: string | null;
|
|
93
|
+
} | null;
|
|
94
|
+
deep_checked: boolean;
|
|
95
|
+
}
|
|
96
|
+
interface DeriveOptions {
|
|
97
|
+
now?: Date;
|
|
98
|
+
}
|
|
99
|
+
export interface PacketInputs {
|
|
100
|
+
/** Parsed tasks.yaml document (may be any YAML value; wrapped by asRecord). */
|
|
101
|
+
tasksDoc: unknown;
|
|
102
|
+
/** Raw spec.md text. */
|
|
103
|
+
specText: string;
|
|
104
|
+
}
|
|
105
|
+
export declare function derivePacketStatusFromInputs(packetDir: string, inputs: PacketInputs, options?: DeriveOptions): PacketStatus;
|
|
106
|
+
export declare function derivePacketStatus(packetDir: string, options?: DeriveOptions): PacketStatus;
|
|
107
|
+
export declare function nextActionText(action: PacketNextAction): string;
|
|
108
|
+
export interface DeepStatus {
|
|
109
|
+
source_authority: string;
|
|
110
|
+
work_evidence: string;
|
|
111
|
+
last_learning: string | null;
|
|
112
|
+
}
|
|
113
|
+
export interface RenderOptions {
|
|
114
|
+
json?: boolean;
|
|
115
|
+
deep?: boolean;
|
|
116
|
+
rich?: boolean;
|
|
117
|
+
color?: boolean;
|
|
118
|
+
bars?: boolean;
|
|
119
|
+
html?: boolean;
|
|
120
|
+
now?: Date;
|
|
121
|
+
glyphs?: boolean;
|
|
122
|
+
}
|
|
123
|
+
export declare function renderAspStatus(packetDir: string, options?: RenderOptions): string;
|
|
124
|
+
export declare function renderStatusHtml(s: PacketStatus): string;
|
|
125
|
+
export {};
|