create-egregore 0.20.2 → 0.21.0-runtime-mvp.2
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/assets/egregore-launcher.js +1013 -16
- package/bin/cli.js +11 -0
- package/lib/claude-runtime.js +192 -0
- package/lib/local.js +38 -31
- package/lib/pi-runtime.js +1 -0
- package/lib/prime-runtime.js +1 -0
- package/lib/runtime-identity.js +146 -0
- package/lib/setup.js +116 -17
- package/package.json +10 -6
- package/runtime/claude/.claude/context/commit-format.md +110 -0
- package/runtime/claude/.claude/context/git-language.md +46 -0
- package/runtime/claude/.claude/context/notification-consent.md +66 -0
- package/runtime/claude/.claude/context/pr-format.md +67 -0
- package/runtime/claude/.claude/context/telemetry.md +133 -0
- package/runtime/claude/.claude/hooks/boundary-check.sh +333 -0
- package/runtime/claude/.claude/hooks/branch-guard.sh +231 -0
- package/runtime/claude/.claude/hooks/card-context.sh +38 -0
- package/runtime/claude/.claude/hooks/emissary-detect.sh +53 -0
- package/runtime/claude/.claude/hooks/memory-refresh.sh +67 -0
- package/runtime/claude/.claude/hooks/onboarding-guard.sh +86 -0
- package/runtime/claude/.claude/hooks/retrieval-context.sh +43 -0
- package/runtime/claude/.claude/rules/voice-bedrock.md +73 -0
- package/runtime/claude/.claude/settings.json +131 -0
- package/runtime/claude/.claude/skills/activity/SKILL.md +68 -0
- package/runtime/claude/.claude/skills/announce/SKILL.md +54 -0
- package/runtime/claude/.claude/skills/archive/SKILL.md +71 -0
- package/runtime/claude/.claude/skills/branch/SKILL.md +147 -0
- package/runtime/claude/.claude/skills/checkup/SKILL.md +159 -0
- package/runtime/claude/.claude/skills/commit/SKILL.md +103 -0
- package/runtime/claude/.claude/skills/contribute/SKILL.md +343 -0
- package/runtime/claude/.claude/skills/create-skill/SKILL.md +135 -0
- package/runtime/claude/.claude/skills/dark-mode/SKILL.md +410 -0
- package/runtime/claude/.claude/skills/dashboard/SKILL.md +43 -0
- package/runtime/claude/.claude/skills/deep-reflect/REPORT.md +140 -0
- package/runtime/claude/.claude/skills/deep-reflect/RESEARCH.md +132 -0
- package/runtime/claude/.claude/skills/deep-reflect/ROLES.md +104 -0
- package/runtime/claude/.claude/skills/deep-reflect/SKILL.md +170 -0
- package/runtime/claude/.claude/skills/delete-user/SKILL.md +150 -0
- package/runtime/claude/.claude/skills/emissary/SKILL.md +220 -0
- package/runtime/claude/.claude/skills/handoff/SKILL.md +124 -0
- package/runtime/claude/.claude/skills/harvest/AUDIT.md +546 -0
- package/runtime/claude/.claude/skills/harvest/FORMAT.md +436 -0
- package/runtime/claude/.claude/skills/harvest/PROCESS.md +395 -0
- package/runtime/claude/.claude/skills/harvest/QUESTION_PALETTE.md +76 -0
- package/runtime/claude/.claude/skills/harvest/SKILL.md +100 -0
- package/runtime/claude/.claude/skills/ingest/SKILL.md +112 -0
- package/runtime/claude/.claude/skills/ingest-corpus/SKILL.md +187 -0
- package/runtime/claude/.claude/skills/ingest-notion/SKILL.md +214 -0
- package/runtime/claude/.claude/skills/ingest-user-interview/SKILL.md +65 -0
- package/runtime/claude/.claude/skills/ingest-user-interview/references/analysis-contract.md +125 -0
- package/runtime/claude/.claude/skills/invite/SKILL.md +111 -0
- package/runtime/claude/.claude/skills/issue/SKILL.md +104 -0
- package/runtime/claude/.claude/skills/me/SKILL.md +81 -0
- package/runtime/claude/.claude/skills/meeting/SKILL.md +76 -0
- package/runtime/claude/.claude/skills/meeting/references/analysis-contract.md +102 -0
- package/runtime/claude/.claude/skills/note/SKILL.md +71 -0
- package/runtime/claude/.claude/skills/notion-connect/SKILL.md +124 -0
- package/runtime/claude/.claude/skills/onboarding/SKILL.md +159 -0
- package/runtime/claude/.claude/skills/pr/SKILL.md +85 -0
- package/runtime/claude/.claude/skills/pull/SKILL.md +79 -0
- package/runtime/claude/.claude/skills/push/SKILL.md +47 -0
- package/runtime/claude/.claude/skills/quest/SKILL.md +121 -0
- package/runtime/claude/.claude/skills/reflect/SKILL.md +69 -0
- package/runtime/claude/.claude/skills/review-pr/SKILL.md +276 -0
- package/runtime/claude/.claude/skills/save/SKILL.md +92 -0
- package/runtime/claude/.claude/skills/slack-connect/SKILL.md +148 -0
- package/runtime/claude/.claude/skills/summon/SKILL.md +240 -0
- package/runtime/claude/.claude/skills/sync-repos/SKILL.md +82 -0
- package/runtime/claude/.claude/skills/teams-connect/SKILL.md +216 -0
- package/runtime/claude/.claude/skills/telegram-connect/SKILL.md +110 -0
- package/runtime/claude/.claude/skills/telemetry/SKILL.md +117 -0
- package/runtime/claude/.claude/skills/test/SKILL.md +87 -0
- package/runtime/claude/.claude/skills/the-spiral/SKILL.md +492 -0
- package/runtime/claude/.claude/skills/tui-design/SKILL.md +188 -0
- package/runtime/claude/.claude/skills/tutorial/SKILL.md +100 -0
- package/runtime/claude/.claude/skills/update/SKILL.md +265 -0
- package/runtime/claude/.claude/skills/view/SKILL.md +393 -0
- package/runtime/claude/.claude/skills/view/compose-scaffold.html +221 -0
- package/runtime/claude/.claude/skills/visual-explain/SKILL.md +132 -0
- package/runtime/claude/.claude/skills/wrap/SKILL.md +98 -0
- package/runtime/claude/CLAUDE.md +447 -0
- package/runtime/claude/bin/activity-action.sh +92 -0
- package/runtime/claude/bin/activity-data.sh +17 -0
- package/runtime/claude/bin/agent.sh +783 -0
- package/runtime/claude/bin/artifact-register.sh +164 -0
- package/runtime/claude/bin/artifact-writeback.sh +53 -0
- package/runtime/claude/bin/artifacts.sh +288 -0
- package/runtime/claude/bin/attendant.sh +707 -0
- package/runtime/claude/bin/autosave.sh +112 -0
- package/runtime/claude/bin/boundary.sh +253 -0
- package/runtime/claude/bin/build-sealed-dataroom.mjs +722 -0
- package/runtime/claude/bin/capture-reconcile.sh +69 -0
- package/runtime/claude/bin/capture-run.sh +357 -0
- package/runtime/claude/bin/codex-install-skills.sh +78 -0
- package/runtime/claude/bin/codex-render-spec.mjs +462 -0
- package/runtime/claude/bin/codex-session-start.sh +275 -0
- package/runtime/claude/bin/codex-skill-render.mjs +349 -0
- package/runtime/claude/bin/codex-sync-skills.sh +237 -0
- package/runtime/claude/bin/connect-refresh.sh +33 -0
- package/runtime/claude/bin/contribute-guard.sh +79 -0
- package/runtime/claude/bin/corpus_map.py +806 -0
- package/runtime/claude/bin/corpus_survey.py +304 -0
- package/runtime/claude/bin/dashboard-data.sh +18 -0
- package/runtime/claude/bin/github-auth.sh +121 -0
- package/runtime/claude/bin/graph-batch.sh +86 -0
- package/runtime/claude/bin/graph-op.sh +1106 -0
- package/runtime/claude/bin/graph-projection.sh +54 -0
- package/runtime/claude/bin/graph-wal.sh +242 -0
- package/runtime/claude/bin/graph.sh +267 -0
- package/runtime/claude/bin/handoff-lifecycle-job.sh +146 -0
- package/runtime/claude/bin/handoff-lifecycle.sh +280 -0
- package/runtime/claude/bin/handoff-pr-backfill.sh +86 -0
- package/runtime/claude/bin/handoff-preview.sh +169 -0
- package/runtime/claude/bin/handoff-run.sh +692 -0
- package/runtime/claude/bin/handoff-save-egregore.sh +224 -0
- package/runtime/claude/bin/index-handoff.sh +322 -0
- package/runtime/claude/bin/ingest-graph.sh +86 -0
- package/runtime/claude/bin/ingest-item.sh +10 -0
- package/runtime/claude/bin/ingest-surface.html +495 -0
- package/runtime/claude/bin/ingest.py +1011 -0
- package/runtime/claude/bin/ingest.sh +308 -0
- package/runtime/claude/bin/ingest_graph.py +856 -0
- package/runtime/claude/bin/ingest_surface.py +544 -0
- package/runtime/claude/bin/invite.sh +6 -0
- package/runtime/claude/bin/issue.sh +10 -0
- package/runtime/claude/bin/knowledge.sh +10 -0
- package/runtime/claude/bin/lib/artifact-id.sh +46 -0
- package/runtime/claude/bin/lib/config.sh +136 -0
- package/runtime/claude/bin/lib/context.sh +642 -0
- package/runtime/claude/bin/lib/dashboard-artifact.sh +242 -0
- package/runtime/claude/bin/lib/ensure-develop.sh +183 -0
- package/runtime/claude/bin/lib/git-message.sh +37 -0
- package/runtime/claude/bin/lib/git-sync.sh +494 -0
- package/runtime/claude/bin/lib/greeting.sh +548 -0
- package/runtime/claude/bin/lib/handoff-meta.sh +97 -0
- package/runtime/claude/bin/lib/hash.sh +13 -0
- package/runtime/claude/bin/lib/identity.sh +213 -0
- package/runtime/claude/bin/lib/metrics.sh +374 -0
- package/runtime/claude/bin/lib/noncode.sh +31 -0
- package/runtime/claude/bin/lib/permissions.sh +106 -0
- package/runtime/claude/bin/lib/time.sh +56 -0
- package/runtime/claude/bin/lib/worktree-links.sh +85 -0
- package/runtime/claude/bin/node-run.sh +42 -0
- package/runtime/claude/bin/notification.sh +6 -0
- package/runtime/claude/bin/notify.sh +636 -0
- package/runtime/claude/bin/observe-context.sh +14 -0
- package/runtime/claude/bin/onboarding.sh +6 -0
- package/runtime/claude/bin/person.py +634 -0
- package/runtime/claude/bin/person.sh +481 -0
- package/runtime/claude/bin/pi-render-spec.mjs +140 -0
- package/runtime/claude/bin/post-update.sh +37 -0
- package/runtime/claude/bin/prime-render-spec.mjs +147 -0
- package/runtime/claude/bin/publish-artifact.sh +324 -0
- package/runtime/claude/bin/publish-references.sh +144 -0
- package/runtime/claude/bin/quest.sh +9 -0
- package/runtime/claude/bin/question.sh +8 -0
- package/runtime/claude/bin/repo-state.sh +96 -0
- package/runtime/claude/bin/research-ingest.sh +7 -0
- package/runtime/claude/bin/restore-owned-skills.sh +67 -0
- package/runtime/claude/bin/retrieval_eval.py +385 -0
- package/runtime/claude/bin/runtime-identity.sh +70 -0
- package/runtime/claude/bin/runtime-upgrade.sh +43 -0
- package/runtime/claude/bin/scroll.sh +9 -0
- package/runtime/claude/bin/search.sh +318 -0
- package/runtime/claude/bin/session-autosave.sh +220 -0
- package/runtime/claude/bin/session-log.sh +199 -0
- package/runtime/claude/bin/session-start.sh +696 -0
- package/runtime/claude/bin/settings.sh +532 -0
- package/runtime/claude/bin/startup-check.sh +136 -0
- package/runtime/claude/bin/statusline.sh +41 -0
- package/runtime/claude/bin/telemetry.sh +666 -0
- package/runtime/claude/bin/test-changes.sh +344 -0
- package/runtime/claude/bin/thread.sh +9 -0
- package/runtime/claude/bin/todo.sh +9 -0
- package/runtime/claude/bin/view-render.sh +126 -0
- package/runtime/claude/bin/worktree-create.sh +145 -0
- package/runtime/claude/bin/worktree-remove.sh +50 -0
- package/runtime/claude/bin/worktree.sh +198 -0
- package/runtime/claude/egregore_runtime/__init__.py +228 -0
- package/runtime/claude/egregore_runtime/adapters/__init__.py +5 -0
- package/runtime/claude/egregore_runtime/adapters/invitation.py +237 -0
- package/runtime/claude/egregore_runtime/adapters/notification.py +59 -0
- package/runtime/claude/egregore_runtime/adapters/qmd.py +1701 -0
- package/runtime/claude/egregore_runtime/adapters/qmd_cli.py +210 -0
- package/runtime/claude/egregore_runtime/adapters/qmd_embed_worker.py +59 -0
- package/runtime/claude/egregore_runtime/admin_gate.py +102 -0
- package/runtime/claude/egregore_runtime/artifacts.py +523 -0
- package/runtime/claude/egregore_runtime/contracts.py +499 -0
- package/runtime/claude/egregore_runtime/entitlements.py +85 -0
- package/runtime/claude/egregore_runtime/errors.py +10 -0
- package/runtime/claude/egregore_runtime/graph.py +356 -0
- package/runtime/claude/egregore_runtime/handoff_lookup.py +196 -0
- package/runtime/claude/egregore_runtime/harness_cli.py +1221 -0
- package/runtime/claude/egregore_runtime/identity.py +734 -0
- package/runtime/claude/egregore_runtime/identity_cli.py +91 -0
- package/runtime/claude/egregore_runtime/ingest.py +575 -0
- package/runtime/claude/egregore_runtime/ingest_cli.py +254 -0
- package/runtime/claude/egregore_runtime/ingest_index_cli.py +147 -0
- package/runtime/claude/egregore_runtime/invitation_cli.py +51 -0
- package/runtime/claude/egregore_runtime/invitations.py +116 -0
- package/runtime/claude/egregore_runtime/issue_cli.py +305 -0
- package/runtime/claude/egregore_runtime/issues.py +359 -0
- package/runtime/claude/egregore_runtime/knowledge.py +376 -0
- package/runtime/claude/egregore_runtime/knowledge_cli.py +173 -0
- package/runtime/claude/egregore_runtime/lifecycle.py +888 -0
- package/runtime/claude/egregore_runtime/lifecycle_cli.py +269 -0
- package/runtime/claude/egregore_runtime/notification_cli.py +125 -0
- package/runtime/claude/egregore_runtime/notifications.py +230 -0
- package/runtime/claude/egregore_runtime/observe.py +342 -0
- package/runtime/claude/egregore_runtime/onboarding.py +290 -0
- package/runtime/claude/egregore_runtime/onboarding_cli.py +110 -0
- package/runtime/claude/egregore_runtime/policy.py +144 -0
- package/runtime/claude/egregore_runtime/profile.py +193 -0
- package/runtime/claude/egregore_runtime/quest_cli.py +216 -0
- package/runtime/claude/egregore_runtime/question_cli.py +180 -0
- package/runtime/claude/egregore_runtime/questions.py +304 -0
- package/runtime/claude/egregore_runtime/quests.py +419 -0
- package/runtime/claude/egregore_runtime/readiness.py +379 -0
- package/runtime/claude/egregore_runtime/research_ingest.py +256 -0
- package/runtime/claude/egregore_runtime/research_ingest_cli.py +44 -0
- package/runtime/claude/egregore_runtime/runtime.py +464 -0
- package/runtime/claude/egregore_runtime/scroll_cli.py +185 -0
- package/runtime/claude/egregore_runtime/scrolls.py +726 -0
- package/runtime/claude/egregore_runtime/status.py +412 -0
- package/runtime/claude/egregore_runtime/status_cli.py +174 -0
- package/runtime/claude/egregore_runtime/sync.py +218 -0
- package/runtime/claude/egregore_runtime/teamsync.py +139 -0
- package/runtime/claude/egregore_runtime/telemetry.py +640 -0
- package/runtime/claude/egregore_runtime/thread_cli.py +173 -0
- package/runtime/claude/egregore_runtime/threads.py +517 -0
- package/runtime/claude/egregore_runtime/todo_cli.py +142 -0
- package/runtime/claude/egregore_runtime/todos.py +244 -0
- package/runtime/claude/egregore_runtime/upgrade.py +770 -0
- package/runtime/claude/egregore_runtime/upgrade_worker.py +53 -0
- package/runtime/claude/egregore_runtime/writeback.py +391 -0
- package/runtime/claude/egregore_runtime/writeback_cli.py +114 -0
- package/runtime/claude/manifest.json +284 -0
- package/runtime/codex/.codex/hooks/search-hint.js +21 -52
- package/runtime/codex/.codex/hooks.json +3 -3
- package/runtime/codex/.codex/skills/activity/SKILL.md +23 -66
- package/runtime/codex/.codex/skills/announce/SKILL.md +27 -50
- package/runtime/codex/.codex/skills/archive/SKILL.md +21 -36
- package/runtime/codex/.codex/skills/checkup/SKILL.md +77 -36
- package/runtime/codex/.codex/skills/dark-mode/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/dashboard/SKILL.md +17 -47
- package/runtime/codex/.codex/skills/handoff/SKILL.md +84 -133
- package/runtime/codex/.codex/skills/harvest/SKILL.md +32 -117
- package/runtime/codex/.codex/skills/ingest/SKILL.md +47 -25
- package/runtime/codex/.codex/skills/ingest-user-interview/SKILL.md +18 -36
- package/runtime/codex/.codex/skills/ingest-user-interview/references/analysis-contract.md +42 -0
- package/runtime/codex/.codex/skills/invite/SKILL.md +21 -35
- package/runtime/codex/.codex/skills/issue/SKILL.md +60 -41
- package/runtime/codex/.codex/skills/me/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/meeting/SKILL.md +16 -36
- package/runtime/codex/.codex/skills/meeting/references/analysis-contract.md +48 -0
- package/runtime/codex/.codex/skills/note/SKILL.md +30 -25
- package/runtime/codex/.codex/skills/onboarding/SKILL.md +36 -41
- package/runtime/codex/.codex/skills/pull/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/quest/SKILL.md +27 -66
- package/runtime/codex/.codex/skills/reflect/SKILL.md +22 -36
- package/runtime/codex/.codex/skills/save/SKILL.md +2 -2
- package/runtime/codex/.codex/skills/telemetry/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/test/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/tutorial/SKILL.md +40 -41
- package/runtime/codex/.codex/skills/view/SKILL.md +115 -111
- package/runtime/codex/.codex/skills/wrap/SKILL.md +45 -41
- package/runtime/codex/.codex/spec-manifest.json +9 -9
- package/runtime/codex/AGENTS.md +62 -58
- package/runtime/codex/bin/activity-action.sh +92 -0
- package/runtime/codex/bin/activity-data.sh +12 -233
- package/runtime/codex/bin/agent.sh +84 -100
- package/runtime/codex/bin/artifact-register.sh +164 -0
- package/runtime/codex/bin/artifact-writeback.sh +53 -0
- package/runtime/codex/bin/artifacts.sh +288 -0
- package/runtime/codex/bin/build-sealed-dataroom.mjs +722 -0
- package/runtime/codex/bin/capture-run.sh +18 -2
- package/runtime/codex/bin/codex-render-spec.mjs +41 -16
- package/runtime/codex/bin/codex-session-start.sh +14 -4
- package/runtime/codex/bin/codex-skill-render.mjs +9 -7
- package/runtime/codex/bin/corpus_map.py +806 -0
- package/runtime/codex/bin/corpus_survey.py +304 -0
- package/runtime/codex/bin/dashboard-data.sh +11 -171
- package/runtime/codex/bin/github-auth.sh +121 -0
- package/runtime/codex/bin/graph-batch.sh +7 -0
- package/runtime/codex/bin/graph-op.sh +4 -0
- package/runtime/codex/bin/graph-projection.sh +54 -0
- package/runtime/codex/bin/graph-wal.sh +13 -0
- package/runtime/codex/bin/graph.sh +44 -0
- package/runtime/codex/bin/handoff-lifecycle-job.sh +146 -0
- package/runtime/codex/bin/handoff-lifecycle.sh +280 -0
- package/runtime/codex/bin/handoff-preview.sh +169 -0
- package/runtime/codex/bin/handoff-run.sh +42 -26
- package/runtime/codex/bin/ingest-graph.sh +6 -0
- package/runtime/codex/bin/ingest-item.sh +10 -0
- package/runtime/codex/bin/ingest.sh +59 -30
- package/runtime/codex/bin/invite.sh +6 -0
- package/runtime/codex/bin/issue.sh +10 -0
- package/runtime/codex/bin/knowledge.sh +10 -0
- package/runtime/codex/bin/lib/config.sh +20 -0
- package/runtime/codex/bin/lib/context.sh +46 -25
- package/runtime/codex/bin/lib/git-sync.sh +70 -6
- package/runtime/codex/bin/lib/greeting.sh +34 -5
- package/runtime/codex/bin/lib/handoff-meta.sh +97 -0
- package/runtime/codex/bin/lib/worktree-links.sh +6 -0
- package/runtime/codex/bin/node-run.sh +42 -0
- package/runtime/codex/bin/notification.sh +6 -0
- package/runtime/codex/bin/observe-context.sh +14 -0
- package/runtime/codex/bin/onboarding.sh +6 -0
- package/runtime/codex/bin/person.py +4 -0
- package/runtime/codex/bin/person.sh +43 -10
- package/runtime/codex/bin/pi-render-spec.mjs +140 -0
- package/runtime/codex/bin/post-update.sh +37 -0
- package/runtime/codex/bin/prime-render-spec.mjs +147 -0
- package/runtime/codex/bin/publish-artifact.sh +55 -2
- package/runtime/codex/bin/quest.sh +9 -0
- package/runtime/codex/bin/question.sh +8 -0
- package/runtime/codex/bin/research-ingest.sh +7 -0
- package/runtime/codex/bin/restore-owned-skills.sh +67 -0
- package/runtime/codex/bin/retrieval_eval.py +385 -0
- package/runtime/codex/bin/runtime-identity.sh +70 -0
- package/runtime/codex/bin/runtime-upgrade.sh +43 -0
- package/runtime/codex/bin/scroll.sh +9 -0
- package/runtime/codex/bin/search.sh +231 -195
- package/runtime/codex/bin/settings.sh +174 -5
- package/runtime/codex/bin/startup-check.sh +136 -0
- package/runtime/codex/bin/telemetry.sh +522 -247
- package/runtime/codex/bin/test-changes.sh +344 -0
- package/runtime/codex/bin/thread.sh +9 -0
- package/runtime/codex/bin/todo.sh +9 -0
- package/runtime/codex/bin/view-render.sh +126 -0
- package/runtime/codex/bin/worktree-create.sh +19 -5
- package/runtime/codex/egregore_runtime/__init__.py +228 -0
- package/runtime/codex/egregore_runtime/adapters/__init__.py +5 -0
- package/runtime/codex/egregore_runtime/adapters/invitation.py +237 -0
- package/runtime/codex/egregore_runtime/adapters/notification.py +59 -0
- package/runtime/codex/egregore_runtime/adapters/qmd.py +1701 -0
- package/runtime/codex/egregore_runtime/adapters/qmd_cli.py +210 -0
- package/runtime/codex/egregore_runtime/adapters/qmd_embed_worker.py +59 -0
- package/runtime/codex/egregore_runtime/admin_gate.py +102 -0
- package/runtime/codex/egregore_runtime/artifacts.py +523 -0
- package/runtime/codex/egregore_runtime/contracts.py +499 -0
- package/runtime/codex/egregore_runtime/entitlements.py +85 -0
- package/runtime/codex/egregore_runtime/errors.py +10 -0
- package/runtime/codex/egregore_runtime/graph.py +356 -0
- package/runtime/codex/egregore_runtime/handoff_lookup.py +196 -0
- package/runtime/codex/egregore_runtime/harness_cli.py +1221 -0
- package/runtime/codex/egregore_runtime/identity.py +734 -0
- package/runtime/codex/egregore_runtime/identity_cli.py +91 -0
- package/runtime/codex/egregore_runtime/ingest.py +575 -0
- package/runtime/codex/egregore_runtime/ingest_cli.py +254 -0
- package/runtime/codex/egregore_runtime/ingest_index_cli.py +147 -0
- package/runtime/codex/egregore_runtime/invitation_cli.py +51 -0
- package/runtime/codex/egregore_runtime/invitations.py +116 -0
- package/runtime/codex/egregore_runtime/issue_cli.py +305 -0
- package/runtime/codex/egregore_runtime/issues.py +359 -0
- package/runtime/codex/egregore_runtime/knowledge.py +376 -0
- package/runtime/codex/egregore_runtime/knowledge_cli.py +173 -0
- package/runtime/codex/egregore_runtime/lifecycle.py +888 -0
- package/runtime/codex/egregore_runtime/lifecycle_cli.py +269 -0
- package/runtime/codex/egregore_runtime/notification_cli.py +125 -0
- package/runtime/codex/egregore_runtime/notifications.py +230 -0
- package/runtime/codex/egregore_runtime/observe.py +342 -0
- package/runtime/codex/egregore_runtime/onboarding.py +290 -0
- package/runtime/codex/egregore_runtime/onboarding_cli.py +110 -0
- package/runtime/codex/egregore_runtime/policy.py +144 -0
- package/runtime/codex/egregore_runtime/profile.py +193 -0
- package/runtime/codex/egregore_runtime/quest_cli.py +216 -0
- package/runtime/codex/egregore_runtime/question_cli.py +180 -0
- package/runtime/codex/egregore_runtime/questions.py +304 -0
- package/runtime/codex/egregore_runtime/quests.py +419 -0
- package/runtime/codex/egregore_runtime/readiness.py +379 -0
- package/runtime/codex/egregore_runtime/research_ingest.py +256 -0
- package/runtime/codex/egregore_runtime/research_ingest_cli.py +44 -0
- package/runtime/codex/egregore_runtime/runtime.py +464 -0
- package/runtime/codex/egregore_runtime/scroll_cli.py +185 -0
- package/runtime/codex/egregore_runtime/scrolls.py +726 -0
- package/runtime/codex/egregore_runtime/status.py +412 -0
- package/runtime/codex/egregore_runtime/status_cli.py +174 -0
- package/runtime/codex/egregore_runtime/sync.py +218 -0
- package/runtime/codex/egregore_runtime/teamsync.py +139 -0
- package/runtime/codex/egregore_runtime/telemetry.py +640 -0
- package/runtime/codex/egregore_runtime/thread_cli.py +173 -0
- package/runtime/codex/egregore_runtime/threads.py +517 -0
- package/runtime/codex/egregore_runtime/todo_cli.py +142 -0
- package/runtime/codex/egregore_runtime/todos.py +244 -0
- package/runtime/codex/egregore_runtime/upgrade.py +770 -0
- package/runtime/codex/egregore_runtime/upgrade_worker.py +53 -0
- package/runtime/codex/egregore_runtime/writeback.py +391 -0
- package/runtime/codex/egregore_runtime/writeback_cli.py +114 -0
- package/runtime/codex/manifest.json +98 -1
- package/runtime/pi/.codex/hooks/search-hint.js +21 -52
- package/runtime/pi/.codex/hooks.json +3 -3
- package/runtime/pi/.codex/skills/activity/SKILL.md +23 -66
- package/runtime/pi/.codex/skills/announce/SKILL.md +27 -50
- package/runtime/pi/.codex/skills/archive/SKILL.md +21 -36
- package/runtime/pi/.codex/skills/checkup/SKILL.md +77 -36
- package/runtime/pi/.codex/skills/dark-mode/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/dashboard/SKILL.md +17 -47
- package/runtime/pi/.codex/skills/handoff/SKILL.md +84 -133
- package/runtime/pi/.codex/skills/harvest/SKILL.md +32 -117
- package/runtime/pi/.codex/skills/ingest/SKILL.md +47 -25
- package/runtime/pi/.codex/skills/ingest-user-interview/SKILL.md +18 -36
- package/runtime/pi/.codex/skills/ingest-user-interview/references/analysis-contract.md +42 -0
- package/runtime/pi/.codex/skills/invite/SKILL.md +21 -35
- package/runtime/pi/.codex/skills/issue/SKILL.md +60 -41
- package/runtime/pi/.codex/skills/me/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/meeting/SKILL.md +16 -36
- package/runtime/pi/.codex/skills/meeting/references/analysis-contract.md +48 -0
- package/runtime/pi/.codex/skills/note/SKILL.md +30 -25
- package/runtime/pi/.codex/skills/onboarding/SKILL.md +36 -41
- package/runtime/pi/.codex/skills/pull/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/quest/SKILL.md +27 -66
- package/runtime/pi/.codex/skills/reflect/SKILL.md +22 -36
- package/runtime/pi/.codex/skills/save/SKILL.md +2 -2
- package/runtime/pi/.codex/skills/telemetry/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/test/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/tutorial/SKILL.md +40 -41
- package/runtime/pi/.codex/skills/view/SKILL.md +115 -111
- package/runtime/pi/.codex/skills/wrap/SKILL.md +45 -41
- package/runtime/pi/.codex/spec-manifest.json +9 -9
- package/runtime/pi/.pi/APPEND_SYSTEM.md +57 -48
- package/runtime/pi/.pi/extensions/egregore.ts +7 -0
- package/runtime/pi/.pi/spec-manifest.json +2 -2
- package/runtime/pi/AGENTS.md +62 -58
- package/runtime/pi/bin/activity-action.sh +92 -0
- package/runtime/pi/bin/activity-data.sh +12 -233
- package/runtime/pi/bin/agent.sh +84 -100
- package/runtime/pi/bin/artifact-register.sh +164 -0
- package/runtime/pi/bin/artifact-writeback.sh +53 -0
- package/runtime/pi/bin/artifacts.sh +288 -0
- package/runtime/pi/bin/build-sealed-dataroom.mjs +722 -0
- package/runtime/pi/bin/capture-run.sh +18 -2
- package/runtime/pi/bin/codex-render-spec.mjs +41 -16
- package/runtime/pi/bin/codex-session-start.sh +14 -4
- package/runtime/pi/bin/codex-skill-render.mjs +9 -7
- package/runtime/pi/bin/corpus_map.py +806 -0
- package/runtime/pi/bin/corpus_survey.py +304 -0
- package/runtime/pi/bin/dashboard-data.sh +11 -171
- package/runtime/pi/bin/github-auth.sh +121 -0
- package/runtime/pi/bin/graph-batch.sh +7 -0
- package/runtime/pi/bin/graph-op.sh +4 -0
- package/runtime/pi/bin/graph-projection.sh +54 -0
- package/runtime/pi/bin/graph-wal.sh +13 -0
- package/runtime/pi/bin/graph.sh +44 -0
- package/runtime/pi/bin/handoff-lifecycle-job.sh +146 -0
- package/runtime/pi/bin/handoff-lifecycle.sh +280 -0
- package/runtime/pi/bin/handoff-preview.sh +169 -0
- package/runtime/pi/bin/handoff-run.sh +42 -26
- package/runtime/pi/bin/ingest-graph.sh +6 -0
- package/runtime/pi/bin/ingest-item.sh +10 -0
- package/runtime/pi/bin/ingest.sh +59 -30
- package/runtime/pi/bin/invite.sh +6 -0
- package/runtime/pi/bin/issue.sh +10 -0
- package/runtime/pi/bin/knowledge.sh +10 -0
- package/runtime/pi/bin/lib/config.sh +20 -0
- package/runtime/pi/bin/lib/context.sh +46 -25
- package/runtime/pi/bin/lib/git-sync.sh +70 -6
- package/runtime/pi/bin/lib/greeting.sh +34 -5
- package/runtime/pi/bin/lib/handoff-meta.sh +97 -0
- package/runtime/pi/bin/lib/worktree-links.sh +6 -0
- package/runtime/pi/bin/node-run.sh +42 -0
- package/runtime/pi/bin/notification.sh +6 -0
- package/runtime/pi/bin/observe-context.sh +14 -0
- package/runtime/pi/bin/onboarding.sh +6 -0
- package/runtime/pi/bin/person.py +4 -0
- package/runtime/pi/bin/person.sh +43 -10
- package/runtime/pi/bin/pi-observe-context.mjs +93 -0
- package/runtime/pi/bin/pi-product-workflows.mjs +1 -1
- package/runtime/pi/bin/pi-render-spec.mjs +1 -1
- package/runtime/pi/bin/post-update.sh +37 -0
- package/runtime/pi/bin/prime-render-spec.mjs +147 -0
- package/runtime/pi/bin/publish-artifact.sh +55 -2
- package/runtime/pi/bin/quest.sh +9 -0
- package/runtime/pi/bin/question.sh +8 -0
- package/runtime/pi/bin/research-ingest.sh +7 -0
- package/runtime/pi/bin/restore-owned-skills.sh +67 -0
- package/runtime/pi/bin/retrieval_eval.py +385 -0
- package/runtime/pi/bin/runtime-identity.sh +70 -0
- package/runtime/pi/bin/runtime-upgrade.sh +43 -0
- package/runtime/pi/bin/scroll.sh +9 -0
- package/runtime/pi/bin/search.sh +231 -195
- package/runtime/pi/bin/settings.sh +174 -5
- package/runtime/pi/bin/startup-check.sh +136 -0
- package/runtime/pi/bin/telemetry.sh +522 -247
- package/runtime/pi/bin/test-changes.sh +344 -0
- package/runtime/pi/bin/thread.sh +9 -0
- package/runtime/pi/bin/todo.sh +9 -0
- package/runtime/pi/bin/view-render.sh +126 -0
- package/runtime/pi/bin/worktree-create.sh +19 -5
- package/runtime/pi/egregore_runtime/__init__.py +228 -0
- package/runtime/pi/egregore_runtime/adapters/__init__.py +5 -0
- package/runtime/pi/egregore_runtime/adapters/invitation.py +237 -0
- package/runtime/pi/egregore_runtime/adapters/notification.py +59 -0
- package/runtime/pi/egregore_runtime/adapters/qmd.py +1701 -0
- package/runtime/pi/egregore_runtime/adapters/qmd_cli.py +210 -0
- package/runtime/pi/egregore_runtime/adapters/qmd_embed_worker.py +59 -0
- package/runtime/pi/egregore_runtime/admin_gate.py +102 -0
- package/runtime/pi/egregore_runtime/artifacts.py +523 -0
- package/runtime/pi/egregore_runtime/contracts.py +499 -0
- package/runtime/pi/egregore_runtime/entitlements.py +85 -0
- package/runtime/pi/egregore_runtime/errors.py +10 -0
- package/runtime/pi/egregore_runtime/graph.py +356 -0
- package/runtime/pi/egregore_runtime/handoff_lookup.py +196 -0
- package/runtime/pi/egregore_runtime/harness_cli.py +1221 -0
- package/runtime/pi/egregore_runtime/identity.py +734 -0
- package/runtime/pi/egregore_runtime/identity_cli.py +91 -0
- package/runtime/pi/egregore_runtime/ingest.py +575 -0
- package/runtime/pi/egregore_runtime/ingest_cli.py +254 -0
- package/runtime/pi/egregore_runtime/ingest_index_cli.py +147 -0
- package/runtime/pi/egregore_runtime/invitation_cli.py +51 -0
- package/runtime/pi/egregore_runtime/invitations.py +116 -0
- package/runtime/pi/egregore_runtime/issue_cli.py +305 -0
- package/runtime/pi/egregore_runtime/issues.py +359 -0
- package/runtime/pi/egregore_runtime/knowledge.py +376 -0
- package/runtime/pi/egregore_runtime/knowledge_cli.py +173 -0
- package/runtime/pi/egregore_runtime/lifecycle.py +888 -0
- package/runtime/pi/egregore_runtime/lifecycle_cli.py +269 -0
- package/runtime/pi/egregore_runtime/notification_cli.py +125 -0
- package/runtime/pi/egregore_runtime/notifications.py +230 -0
- package/runtime/pi/egregore_runtime/observe.py +342 -0
- package/runtime/pi/egregore_runtime/onboarding.py +290 -0
- package/runtime/pi/egregore_runtime/onboarding_cli.py +110 -0
- package/runtime/pi/egregore_runtime/policy.py +144 -0
- package/runtime/pi/egregore_runtime/profile.py +193 -0
- package/runtime/pi/egregore_runtime/quest_cli.py +216 -0
- package/runtime/pi/egregore_runtime/question_cli.py +180 -0
- package/runtime/pi/egregore_runtime/questions.py +304 -0
- package/runtime/pi/egregore_runtime/quests.py +419 -0
- package/runtime/pi/egregore_runtime/readiness.py +379 -0
- package/runtime/pi/egregore_runtime/research_ingest.py +256 -0
- package/runtime/pi/egregore_runtime/research_ingest_cli.py +44 -0
- package/runtime/pi/egregore_runtime/runtime.py +464 -0
- package/runtime/pi/egregore_runtime/scroll_cli.py +185 -0
- package/runtime/pi/egregore_runtime/scrolls.py +726 -0
- package/runtime/pi/egregore_runtime/status.py +412 -0
- package/runtime/pi/egregore_runtime/status_cli.py +174 -0
- package/runtime/pi/egregore_runtime/sync.py +218 -0
- package/runtime/pi/egregore_runtime/teamsync.py +139 -0
- package/runtime/pi/egregore_runtime/telemetry.py +640 -0
- package/runtime/pi/egregore_runtime/thread_cli.py +173 -0
- package/runtime/pi/egregore_runtime/threads.py +517 -0
- package/runtime/pi/egregore_runtime/todo_cli.py +142 -0
- package/runtime/pi/egregore_runtime/todos.py +244 -0
- package/runtime/pi/egregore_runtime/upgrade.py +770 -0
- package/runtime/pi/egregore_runtime/upgrade_worker.py +53 -0
- package/runtime/pi/egregore_runtime/writeback.py +391 -0
- package/runtime/pi/egregore_runtime/writeback_cli.py +114 -0
- package/runtime/pi/manifest.json +98 -1
- package/runtime/prime/.codex/hooks/search-hint.js +21 -52
- package/runtime/prime/.codex/hooks.json +3 -3
- package/runtime/prime/.codex/skills/activity/SKILL.md +23 -66
- package/runtime/prime/.codex/skills/announce/SKILL.md +27 -50
- package/runtime/prime/.codex/skills/archive/SKILL.md +21 -36
- package/runtime/prime/.codex/skills/checkup/SKILL.md +77 -36
- package/runtime/prime/.codex/skills/dark-mode/SKILL.md +1 -1
- package/runtime/prime/.codex/skills/dashboard/SKILL.md +17 -47
- package/runtime/prime/.codex/skills/handoff/SKILL.md +84 -133
- package/runtime/prime/.codex/skills/harvest/SKILL.md +32 -117
- package/runtime/prime/.codex/skills/ingest/SKILL.md +47 -25
- package/runtime/prime/.codex/skills/ingest-user-interview/SKILL.md +18 -36
- package/runtime/prime/.codex/skills/ingest-user-interview/references/analysis-contract.md +42 -0
- package/runtime/prime/.codex/skills/invite/SKILL.md +21 -35
- package/runtime/prime/.codex/skills/issue/SKILL.md +60 -41
- package/runtime/prime/.codex/skills/me/SKILL.md +1 -1
- package/runtime/prime/.codex/skills/meeting/SKILL.md +16 -36
- package/runtime/prime/.codex/skills/meeting/references/analysis-contract.md +48 -0
- package/runtime/prime/.codex/skills/note/SKILL.md +30 -25
- package/runtime/prime/.codex/skills/onboarding/SKILL.md +36 -41
- package/runtime/prime/.codex/skills/pull/SKILL.md +1 -1
- package/runtime/prime/.codex/skills/quest/SKILL.md +27 -66
- package/runtime/prime/.codex/skills/reflect/SKILL.md +22 -36
- package/runtime/prime/.codex/skills/save/SKILL.md +2 -2
- package/runtime/prime/.codex/skills/telemetry/SKILL.md +1 -1
- package/runtime/prime/.codex/skills/test/SKILL.md +1 -1
- package/runtime/prime/.codex/skills/tutorial/SKILL.md +40 -41
- package/runtime/prime/.codex/skills/view/SKILL.md +115 -111
- package/runtime/prime/.codex/skills/wrap/SKILL.md +45 -41
- package/runtime/prime/.codex/spec-manifest.json +9 -9
- package/runtime/prime/.prime/agent/APPEND_SYSTEM.md +57 -48
- package/runtime/prime/.prime/agent/extensions/egregore.ts +7 -0
- package/runtime/prime/.prime/agent/spec-manifest.json +2 -2
- package/runtime/prime/AGENTS.md +62 -58
- package/runtime/prime/bin/activity-action.sh +92 -0
- package/runtime/prime/bin/activity-data.sh +12 -233
- package/runtime/prime/bin/agent.sh +84 -100
- package/runtime/prime/bin/artifact-register.sh +164 -0
- package/runtime/prime/bin/artifact-writeback.sh +53 -0
- package/runtime/prime/bin/artifacts.sh +288 -0
- package/runtime/prime/bin/build-sealed-dataroom.mjs +722 -0
- package/runtime/prime/bin/capture-run.sh +18 -2
- package/runtime/prime/bin/codex-render-spec.mjs +41 -16
- package/runtime/prime/bin/codex-session-start.sh +14 -4
- package/runtime/prime/bin/codex-skill-render.mjs +9 -7
- package/runtime/prime/bin/corpus_map.py +806 -0
- package/runtime/prime/bin/corpus_survey.py +304 -0
- package/runtime/prime/bin/dashboard-data.sh +11 -171
- package/runtime/prime/bin/github-auth.sh +121 -0
- package/runtime/prime/bin/graph-batch.sh +7 -0
- package/runtime/prime/bin/graph-op.sh +4 -0
- package/runtime/prime/bin/graph-projection.sh +54 -0
- package/runtime/prime/bin/graph-wal.sh +13 -0
- package/runtime/prime/bin/graph.sh +44 -0
- package/runtime/prime/bin/handoff-lifecycle-job.sh +146 -0
- package/runtime/prime/bin/handoff-lifecycle.sh +280 -0
- package/runtime/prime/bin/handoff-preview.sh +169 -0
- package/runtime/prime/bin/handoff-run.sh +42 -26
- package/runtime/prime/bin/ingest-graph.sh +6 -0
- package/runtime/prime/bin/ingest-item.sh +10 -0
- package/runtime/prime/bin/ingest.sh +59 -30
- package/runtime/prime/bin/invite.sh +6 -0
- package/runtime/prime/bin/issue.sh +10 -0
- package/runtime/prime/bin/knowledge.sh +10 -0
- package/runtime/prime/bin/lib/config.sh +20 -0
- package/runtime/prime/bin/lib/context.sh +46 -25
- package/runtime/prime/bin/lib/git-sync.sh +70 -6
- package/runtime/prime/bin/lib/greeting.sh +34 -5
- package/runtime/prime/bin/lib/handoff-meta.sh +97 -0
- package/runtime/prime/bin/lib/worktree-links.sh +6 -0
- package/runtime/prime/bin/node-run.sh +42 -0
- package/runtime/prime/bin/notification.sh +6 -0
- package/runtime/prime/bin/observe-context.sh +14 -0
- package/runtime/prime/bin/onboarding.sh +6 -0
- package/runtime/prime/bin/person.py +4 -0
- package/runtime/prime/bin/person.sh +43 -10
- package/runtime/prime/bin/pi-observe-context.mjs +93 -0
- package/runtime/prime/bin/pi-product-workflows.mjs +1 -1
- package/runtime/prime/bin/pi-render-spec.mjs +140 -0
- package/runtime/prime/bin/post-update.sh +37 -0
- package/runtime/prime/bin/prime-render-spec.mjs +1 -1
- package/runtime/prime/bin/publish-artifact.sh +55 -2
- package/runtime/prime/bin/quest.sh +9 -0
- package/runtime/prime/bin/question.sh +8 -0
- package/runtime/prime/bin/research-ingest.sh +7 -0
- package/runtime/prime/bin/restore-owned-skills.sh +67 -0
- package/runtime/prime/bin/retrieval_eval.py +385 -0
- package/runtime/prime/bin/runtime-identity.sh +70 -0
- package/runtime/prime/bin/runtime-upgrade.sh +43 -0
- package/runtime/prime/bin/scroll.sh +9 -0
- package/runtime/prime/bin/search.sh +231 -195
- package/runtime/prime/bin/settings.sh +174 -5
- package/runtime/prime/bin/startup-check.sh +136 -0
- package/runtime/prime/bin/telemetry.sh +522 -247
- package/runtime/prime/bin/test-changes.sh +344 -0
- package/runtime/prime/bin/thread.sh +9 -0
- package/runtime/prime/bin/todo.sh +9 -0
- package/runtime/prime/bin/view-render.sh +126 -0
- package/runtime/prime/bin/worktree-create.sh +19 -5
- package/runtime/prime/egregore_runtime/__init__.py +228 -0
- package/runtime/prime/egregore_runtime/adapters/__init__.py +5 -0
- package/runtime/prime/egregore_runtime/adapters/invitation.py +237 -0
- package/runtime/prime/egregore_runtime/adapters/notification.py +59 -0
- package/runtime/prime/egregore_runtime/adapters/qmd.py +1701 -0
- package/runtime/prime/egregore_runtime/adapters/qmd_cli.py +210 -0
- package/runtime/prime/egregore_runtime/adapters/qmd_embed_worker.py +59 -0
- package/runtime/prime/egregore_runtime/admin_gate.py +102 -0
- package/runtime/prime/egregore_runtime/artifacts.py +523 -0
- package/runtime/prime/egregore_runtime/contracts.py +499 -0
- package/runtime/prime/egregore_runtime/entitlements.py +85 -0
- package/runtime/prime/egregore_runtime/errors.py +10 -0
- package/runtime/prime/egregore_runtime/graph.py +356 -0
- package/runtime/prime/egregore_runtime/handoff_lookup.py +196 -0
- package/runtime/prime/egregore_runtime/harness_cli.py +1221 -0
- package/runtime/prime/egregore_runtime/identity.py +734 -0
- package/runtime/prime/egregore_runtime/identity_cli.py +91 -0
- package/runtime/prime/egregore_runtime/ingest.py +575 -0
- package/runtime/prime/egregore_runtime/ingest_cli.py +254 -0
- package/runtime/prime/egregore_runtime/ingest_index_cli.py +147 -0
- package/runtime/prime/egregore_runtime/invitation_cli.py +51 -0
- package/runtime/prime/egregore_runtime/invitations.py +116 -0
- package/runtime/prime/egregore_runtime/issue_cli.py +305 -0
- package/runtime/prime/egregore_runtime/issues.py +359 -0
- package/runtime/prime/egregore_runtime/knowledge.py +376 -0
- package/runtime/prime/egregore_runtime/knowledge_cli.py +173 -0
- package/runtime/prime/egregore_runtime/lifecycle.py +888 -0
- package/runtime/prime/egregore_runtime/lifecycle_cli.py +269 -0
- package/runtime/prime/egregore_runtime/notification_cli.py +125 -0
- package/runtime/prime/egregore_runtime/notifications.py +230 -0
- package/runtime/prime/egregore_runtime/observe.py +342 -0
- package/runtime/prime/egregore_runtime/onboarding.py +290 -0
- package/runtime/prime/egregore_runtime/onboarding_cli.py +110 -0
- package/runtime/prime/egregore_runtime/policy.py +144 -0
- package/runtime/prime/egregore_runtime/profile.py +193 -0
- package/runtime/prime/egregore_runtime/quest_cli.py +216 -0
- package/runtime/prime/egregore_runtime/question_cli.py +180 -0
- package/runtime/prime/egregore_runtime/questions.py +304 -0
- package/runtime/prime/egregore_runtime/quests.py +419 -0
- package/runtime/prime/egregore_runtime/readiness.py +379 -0
- package/runtime/prime/egregore_runtime/research_ingest.py +256 -0
- package/runtime/prime/egregore_runtime/research_ingest_cli.py +44 -0
- package/runtime/prime/egregore_runtime/runtime.py +464 -0
- package/runtime/prime/egregore_runtime/scroll_cli.py +185 -0
- package/runtime/prime/egregore_runtime/scrolls.py +726 -0
- package/runtime/prime/egregore_runtime/status.py +412 -0
- package/runtime/prime/egregore_runtime/status_cli.py +174 -0
- package/runtime/prime/egregore_runtime/sync.py +218 -0
- package/runtime/prime/egregore_runtime/teamsync.py +139 -0
- package/runtime/prime/egregore_runtime/telemetry.py +640 -0
- package/runtime/prime/egregore_runtime/thread_cli.py +173 -0
- package/runtime/prime/egregore_runtime/threads.py +517 -0
- package/runtime/prime/egregore_runtime/todo_cli.py +142 -0
- package/runtime/prime/egregore_runtime/todos.py +244 -0
- package/runtime/prime/egregore_runtime/upgrade.py +770 -0
- package/runtime/prime/egregore_runtime/upgrade_worker.py +53 -0
- package/runtime/prime/egregore_runtime/writeback.py +391 -0
- package/runtime/prime/egregore_runtime/writeback_cli.py +114 -0
- package/runtime/prime/manifest.json +98 -1
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# repo-state.sh — Capture current branch state across all repos.
|
|
3
|
+
# Outputs a markdown table (## Repo State) for handoff files.
|
|
4
|
+
# Only includes repos on non-base branches or with uncommitted changes.
|
|
5
|
+
#
|
|
6
|
+
# Usage: bash bin/repo-state.sh [--no-pr]
|
|
7
|
+
# --no-pr Skip the `gh pr list` lookup per repo (~400–600ms each).
|
|
8
|
+
# PR column will be `—`. Useful on the hot path where a detached
|
|
9
|
+
# backfill will fill PR numbers in later.
|
|
10
|
+
# Outputs the markdown section to stdout. Empty output = nothing to report.
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
|
|
13
|
+
NO_PR=0
|
|
14
|
+
while [ $# -gt 0 ]; do
|
|
15
|
+
case "$1" in
|
|
16
|
+
--no-pr) NO_PR=1; shift ;;
|
|
17
|
+
*) shift ;;
|
|
18
|
+
esac
|
|
19
|
+
done
|
|
20
|
+
|
|
21
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
22
|
+
CONFIG="$SCRIPT_DIR/egregore.json"
|
|
23
|
+
PARENT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
24
|
+
|
|
25
|
+
# Source config helpers for _get_base_branch
|
|
26
|
+
source "$SCRIPT_DIR/bin/lib/config.sh" 2>/dev/null || true
|
|
27
|
+
|
|
28
|
+
CORE_REPO=$(jq -r '.repo_name // "egregore"' "$CONFIG" 2>/dev/null)
|
|
29
|
+
GITHUB_ORG=$(jq -r '.github_org // empty' "$CONFIG" 2>/dev/null)
|
|
30
|
+
MANAGED_REPOS=$(jq -r '(.repos[]? // empty) | if type == "object" then .name else . end' "$CONFIG" 2>/dev/null)
|
|
31
|
+
|
|
32
|
+
ROWS=""
|
|
33
|
+
|
|
34
|
+
check_repo() {
|
|
35
|
+
local repo_name="$1"
|
|
36
|
+
local repo_dir="$2"
|
|
37
|
+
local base_branch="$3"
|
|
38
|
+
|
|
39
|
+
[ -d "$repo_dir/.git" ] || [ -f "$repo_dir/.git" ] || return 0
|
|
40
|
+
|
|
41
|
+
local branch
|
|
42
|
+
branch=$(git -C "$repo_dir" branch --show-current 2>/dev/null || echo "")
|
|
43
|
+
[ -z "$branch" ] && return 0
|
|
44
|
+
|
|
45
|
+
local dirty=""
|
|
46
|
+
[ -n "$(git -C "$repo_dir" status --porcelain 2>/dev/null | head -1)" ] && dirty="yes"
|
|
47
|
+
|
|
48
|
+
# Skip if on base branch with no changes
|
|
49
|
+
if [ "$branch" = "$base_branch" ] && [ -z "$dirty" ]; then
|
|
50
|
+
return 0
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# Count commits ahead of base
|
|
54
|
+
local ahead=0
|
|
55
|
+
ahead=$(git -C "$repo_dir" rev-list "origin/${base_branch}..HEAD" --count 2>/dev/null || echo "0")
|
|
56
|
+
|
|
57
|
+
# Skip if on base branch, no dirty files, no commits ahead
|
|
58
|
+
if [ "$branch" = "$base_branch" ] && [ -z "$dirty" ] && [ "$ahead" = "0" ]; then
|
|
59
|
+
return 0
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
# Check for open PR (skipped with --no-pr; a detached backfill fills it in)
|
|
63
|
+
local pr="—"
|
|
64
|
+
if [ "$NO_PR" = "0" ] && command -v gh &>/dev/null && [ -n "$GITHUB_ORG" ]; then
|
|
65
|
+
local pr_num
|
|
66
|
+
pr_num=$(gh pr list --repo "$GITHUB_ORG/$repo_name" --head "$branch" --json number -q '.[0].number' 2>/dev/null || true)
|
|
67
|
+
[ -n "$pr_num" ] && pr="#$pr_num"
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
ROWS="${ROWS}| ${repo_name} | ${branch} | ${pr} | ${base_branch} |\n"
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
# Check core repo
|
|
74
|
+
if ! CORE_BASE=$(_get_base_branch); then
|
|
75
|
+
echo "repo-state: could not resolve the configured base branch" >&2
|
|
76
|
+
exit 1
|
|
77
|
+
fi
|
|
78
|
+
check_repo "$CORE_REPO" "$SCRIPT_DIR" "$CORE_BASE"
|
|
79
|
+
|
|
80
|
+
# Check managed repos
|
|
81
|
+
for REPO in $MANAGED_REPOS; do
|
|
82
|
+
REPO_DIR="$PARENT_DIR/$REPO"
|
|
83
|
+
if ! BASE=$(_get_base_branch "$REPO"); then
|
|
84
|
+
continue
|
|
85
|
+
fi
|
|
86
|
+
check_repo "$REPO" "$REPO_DIR" "$BASE"
|
|
87
|
+
done
|
|
88
|
+
|
|
89
|
+
# Output
|
|
90
|
+
if [ -n "$ROWS" ]; then
|
|
91
|
+
echo "## Repo State"
|
|
92
|
+
echo ""
|
|
93
|
+
echo "| Repo | Branch | PR | Base |"
|
|
94
|
+
echo "|------|--------|----|------|"
|
|
95
|
+
printf '%b' "$ROWS"
|
|
96
|
+
fi
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Typed Runtime boundary for approved meeting/interview analysis packages.
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
6
|
+
EGREGORE_ROOT="$ROOT" PYTHONPATH="$ROOT${PYTHONPATH:+:$PYTHONPATH}" \
|
|
7
|
+
exec python3 -m egregore_runtime.research_ingest_cli "$@"
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# restore-owned-skills.sh — keep org-owned skills intact through a framework update.
|
|
3
|
+
#
|
|
4
|
+
# Org-owned skills are declared in egregore.json → owned_skills[]. The /update
|
|
5
|
+
# overlay stamps upstream framework paths (including .claude/skills/) over the
|
|
6
|
+
# working tree. This script runs AFTER the overlay and BEFORE the update
|
|
7
|
+
# commit. For every owned skill name:
|
|
8
|
+
#
|
|
9
|
+
# - upstream does NOT ship that name → nothing to do (the overlay never
|
|
10
|
+
# touched it; local edits, committed or not, are left alone)
|
|
11
|
+
# - upstream DOES ship that name → the org's committed version wins:
|
|
12
|
+
# the skill directory is reset to HEAD and the collision is reported so
|
|
13
|
+
# the org can rename theirs or explicitly adopt upstream's
|
|
14
|
+
# - collision but no committed org version → upstream's copy stays (there is
|
|
15
|
+
# nothing to restore); the report says to commit and re-run /update
|
|
16
|
+
#
|
|
17
|
+
# Runtime-neutral: called from every harness's update flow. Idempotent; exits
|
|
18
|
+
# 0 silently when owned_skills is absent or empty.
|
|
19
|
+
#
|
|
20
|
+
# Usage: restore-owned-skills.sh [--upstream-ref <ref>] (default upstream/main)
|
|
21
|
+
|
|
22
|
+
set -uo pipefail
|
|
23
|
+
|
|
24
|
+
UPSTREAM_REF="upstream/main"
|
|
25
|
+
if [ "${1:-}" = "--upstream-ref" ] && [ -n "${2:-}" ]; then
|
|
26
|
+
UPSTREAM_REF="$2"
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
command -v jq >/dev/null 2>&1 || exit 0
|
|
30
|
+
[ -f egregore.json ] || exit 0
|
|
31
|
+
git rev-parse --git-dir >/dev/null 2>&1 || exit 0
|
|
32
|
+
|
|
33
|
+
OWNED=$(jq -r '.owned_skills // [] | .[]' egregore.json 2>/dev/null)
|
|
34
|
+
[ -n "$OWNED" ] || exit 0
|
|
35
|
+
|
|
36
|
+
while IFS= read -r name; do
|
|
37
|
+
[ -n "$name" ] || continue
|
|
38
|
+
case "$name" in
|
|
39
|
+
*/*|.*|*..*|*' '*)
|
|
40
|
+
echo " ⚠ owned_skills: invalid name '$name' — skipped" >&2
|
|
41
|
+
continue
|
|
42
|
+
;;
|
|
43
|
+
esac
|
|
44
|
+
SKILL_PATH=".claude/skills/$name"
|
|
45
|
+
|
|
46
|
+
# Only a name collision needs work — an org-only skill is never touched by
|
|
47
|
+
# the overlay, and resetting it here would destroy uncommitted local edits.
|
|
48
|
+
if ! git ls-tree -d "$UPSTREAM_REF" -- "$SKILL_PATH" 2>/dev/null | grep -q .; then
|
|
49
|
+
continue
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
if git cat-file -e "HEAD:$SKILL_PATH" 2>/dev/null; then
|
|
53
|
+
# Wipe the overlay's copy (index + tree), then restore the org's committed
|
|
54
|
+
# version. rm+checkout also drops upstream-only files inside the dir.
|
|
55
|
+
git rm -r --cached --quiet -- "$SKILL_PATH" 2>/dev/null || true
|
|
56
|
+
rm -rf "$SKILL_PATH"
|
|
57
|
+
git checkout HEAD -- "$SKILL_PATH" 2>/dev/null || true
|
|
58
|
+
echo " ◐ owned skill '$name': upstream ships a skill with this name — kept yours."
|
|
59
|
+
echo " Review upstream's version: git diff HEAD $UPSTREAM_REF -- $SKILL_PATH"
|
|
60
|
+
else
|
|
61
|
+
echo " ⚠ owned skill '$name': upstream ships this name and you have no committed version — upstream's copy is in the tree. Commit yours and re-run /update to keep it."
|
|
62
|
+
fi
|
|
63
|
+
done <<EOF
|
|
64
|
+
$OWNED
|
|
65
|
+
EOF
|
|
66
|
+
|
|
67
|
+
exit 0
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
"""Measure retrieval against questions whose answers are known.
|
|
2
|
+
|
|
3
|
+
A system that answers questions phrases a wrong answer exactly as well as a
|
|
4
|
+
right one. Nothing about the output distinguishes them, so the only instrument
|
|
5
|
+
that can is a set of questions someone has already answered — asked of the
|
|
6
|
+
system, and compared.
|
|
7
|
+
|
|
8
|
+
This runs such a fixture and reports what the plan requires: whether the hard
|
|
9
|
+
boundary ever leaked, how often the expected source was retrieved, how often
|
|
10
|
+
nothing was found, and how long it took. A boundary violation is a failure
|
|
11
|
+
regardless of how good the answer looked.
|
|
12
|
+
|
|
13
|
+
Expected answers are marked verified or not. An unverified expectation is a
|
|
14
|
+
guess written down, and counting it as evidence would make the measurement
|
|
15
|
+
agree with whoever wrote the fixture rather than with the domain.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import json
|
|
21
|
+
import math
|
|
22
|
+
import re
|
|
23
|
+
import time
|
|
24
|
+
from collections import Counter
|
|
25
|
+
from dataclasses import dataclass, field
|
|
26
|
+
from pathlib import Path
|
|
27
|
+
|
|
28
|
+
TOKEN = re.compile(r"\w{3,}", re.UNICODE)
|
|
29
|
+
|
|
30
|
+
# Turkish is agglutinative: budama, budaması and budamada are one word wearing
|
|
31
|
+
# three suffixes, and exact token matching treats them as three. Retrieval
|
|
32
|
+
# therefore under-returns on inflected forms. Stemming is a known gap, recorded
|
|
33
|
+
# here rather than silently tolerated — measuring it needs the fixture.
|
|
34
|
+
STEMMING = False
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@dataclass
|
|
38
|
+
class Passage:
|
|
39
|
+
id: str
|
|
40
|
+
text: str
|
|
41
|
+
document: str
|
|
42
|
+
zone: str
|
|
43
|
+
tier: str
|
|
44
|
+
topic: str
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@dataclass
|
|
48
|
+
class QueryResult:
|
|
49
|
+
id: str
|
|
50
|
+
question: str
|
|
51
|
+
found: int
|
|
52
|
+
top: list = field(default_factory=list)
|
|
53
|
+
expected_hit: bool | None = None
|
|
54
|
+
boundary_violation: list = field(default_factory=list)
|
|
55
|
+
elapsed_ms: float = 0.0
|
|
56
|
+
verified_expectation: bool = False
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def tokenize(text: str) -> list[str]:
|
|
60
|
+
return TOKEN.findall((text or "").lower())
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def zones_in_scope(zone: str, hierarchy: dict) -> set[str]:
|
|
64
|
+
"""A zone plus everything it inherits from.
|
|
65
|
+
|
|
66
|
+
Inheritance runs one way. A grower's own zone and the wider zones containing
|
|
67
|
+
it are in scope; a sibling zone never is, which is the direction where a
|
|
68
|
+
violation does harm.
|
|
69
|
+
"""
|
|
70
|
+
scope = {zone}
|
|
71
|
+
current = zone
|
|
72
|
+
seen = {zone}
|
|
73
|
+
while True:
|
|
74
|
+
parent = hierarchy.get(current)
|
|
75
|
+
if not parent or parent in seen:
|
|
76
|
+
break
|
|
77
|
+
scope.add(parent)
|
|
78
|
+
seen.add(parent)
|
|
79
|
+
current = parent
|
|
80
|
+
return scope
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
# BM25 parameters at their standard values. k1 bounds how much repeating a term
|
|
84
|
+
# can raise a score; b sets how strongly length is normalised away.
|
|
85
|
+
K1 = 1.2
|
|
86
|
+
B = 0.75
|
|
87
|
+
|
|
88
|
+
# How many passages one document may contribute. Without a cap a single long
|
|
89
|
+
# document fills the whole list, and a grower reading five results sees one
|
|
90
|
+
# source five times instead of five sources.
|
|
91
|
+
PER_DOCUMENT = 2
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class Index:
|
|
95
|
+
"""A lexical index over passages, filtered before ranking.
|
|
96
|
+
|
|
97
|
+
Ranking is BM25 rather than plain term frequency. The difference is length:
|
|
98
|
+
a longer passage contains more of every word, so under raw counts the
|
|
99
|
+
longest passages in a corpus rise to the top of questions they have no
|
|
100
|
+
particular claim to. Measured here, the two documents topping unrelated
|
|
101
|
+
queries were the two longest chunks in the archive.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
def __init__(self, passages: list[Passage]):
|
|
105
|
+
self.passages = passages
|
|
106
|
+
self.df: Counter = Counter()
|
|
107
|
+
self.tf: list[Counter] = []
|
|
108
|
+
self.lengths: list[int] = []
|
|
109
|
+
for p in passages:
|
|
110
|
+
counts = Counter(tokenize(p.text))
|
|
111
|
+
self.tf.append(counts)
|
|
112
|
+
self.lengths.append(sum(counts.values()))
|
|
113
|
+
self.df.update(set(counts))
|
|
114
|
+
self.n = max(1, len(passages))
|
|
115
|
+
self.avg_length = (sum(self.lengths) / self.n) if self.lengths else 0.0
|
|
116
|
+
|
|
117
|
+
def idf(self, term: str) -> float:
|
|
118
|
+
"""Inverse document frequency, in the form that stays positive.
|
|
119
|
+
|
|
120
|
+
The textbook ratio goes to zero — and can go negative — for a term
|
|
121
|
+
present in most of the corpus, which silently drops passages that do
|
|
122
|
+
match. The +1 keeps every genuine match above zero.
|
|
123
|
+
"""
|
|
124
|
+
df = self.df.get(term, 0)
|
|
125
|
+
return math.log(1 + (self.n - df + 0.5) / (df + 0.5))
|
|
126
|
+
|
|
127
|
+
def search(
|
|
128
|
+
self,
|
|
129
|
+
question: str,
|
|
130
|
+
allowed_zones: set[str],
|
|
131
|
+
limit: int = 5,
|
|
132
|
+
per_document: int = PER_DOCUMENT,
|
|
133
|
+
vocabulary=None,
|
|
134
|
+
) -> list[tuple[float, Passage]]:
|
|
135
|
+
terms = tokenize(question)
|
|
136
|
+
weights = {t: 1.0 for t in terms}
|
|
137
|
+
if vocabulary is not None:
|
|
138
|
+
import term_expand
|
|
139
|
+
|
|
140
|
+
_, added = term_expand.expand(question, vocabulary)
|
|
141
|
+
for t in added:
|
|
142
|
+
# Only where the asker did not already use the word. An inferred
|
|
143
|
+
# word never raises the weight of one they chose themselves.
|
|
144
|
+
if len(t) >= 3 and t not in weights:
|
|
145
|
+
weights[t] = term_expand.EXPANSION_WEIGHT
|
|
146
|
+
|
|
147
|
+
scored = []
|
|
148
|
+
for i, p in enumerate(self.passages):
|
|
149
|
+
# The zone filter runs before ranking, not after. Filtering a ranked
|
|
150
|
+
# list would let a better-scoring out-of-zone passage displace an
|
|
151
|
+
# in-zone one and shorten the result rather than replace it.
|
|
152
|
+
if p.zone not in allowed_zones:
|
|
153
|
+
continue
|
|
154
|
+
counts = self.tf[i]
|
|
155
|
+
norm = K1 * (1 - B + B * (self.lengths[i] / self.avg_length)) if self.avg_length else K1
|
|
156
|
+
score = 0.0
|
|
157
|
+
for t, weight in weights.items():
|
|
158
|
+
tf = counts.get(t, 0)
|
|
159
|
+
if tf:
|
|
160
|
+
score += weight * self.idf(t) * (tf * (K1 + 1)) / (tf + norm)
|
|
161
|
+
if score > 0:
|
|
162
|
+
scored.append((score, p))
|
|
163
|
+
scored.sort(key=lambda x: -x[0])
|
|
164
|
+
|
|
165
|
+
if per_document <= 0:
|
|
166
|
+
return scored[:limit]
|
|
167
|
+
seen: Counter = Counter()
|
|
168
|
+
capped = []
|
|
169
|
+
for score, p in scored:
|
|
170
|
+
if seen[p.document] >= per_document:
|
|
171
|
+
continue
|
|
172
|
+
seen[p.document] += 1
|
|
173
|
+
capped.append((score, p))
|
|
174
|
+
if len(capped) >= limit:
|
|
175
|
+
break
|
|
176
|
+
return capped
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def load_passages(manifest_path: Path, data_root: Path) -> list[Passage]:
|
|
180
|
+
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
|
|
181
|
+
chunk_re = re.compile(r"<!-- ingest-chunk: (\S+) -->\n\n(.*?)(?=\n## Chunk |\Z)", re.S)
|
|
182
|
+
passages: list[Passage] = []
|
|
183
|
+
for doc in manifest.get("documents", []):
|
|
184
|
+
body = (data_root / doc["file_path"]).read_text(encoding="utf-8", errors="replace")
|
|
185
|
+
provenance = doc.get("provenance") or {}
|
|
186
|
+
catalogued = provenance.get("from_catalogue") or {}
|
|
187
|
+
excluded = {
|
|
188
|
+
c["id"] for c in doc.get("chunks", []) if (c.get("segment") or {}).get("kind") == "bibliography"
|
|
189
|
+
}
|
|
190
|
+
for match in chunk_re.finditer(body):
|
|
191
|
+
cid = match.group(1)
|
|
192
|
+
if cid in excluded:
|
|
193
|
+
continue
|
|
194
|
+
passages.append(
|
|
195
|
+
Passage(
|
|
196
|
+
id=cid,
|
|
197
|
+
text=match.group(2),
|
|
198
|
+
document=doc.get("title", ""),
|
|
199
|
+
zone=(doc.get("boundaries") or {}).get("zone", ""),
|
|
200
|
+
tier=provenance.get("tier", ""),
|
|
201
|
+
topic=catalogued.get("topic", ""),
|
|
202
|
+
)
|
|
203
|
+
)
|
|
204
|
+
return passages
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def run(fixture: dict, index: Index, vocabulary=None) -> list[QueryResult]:
|
|
208
|
+
hierarchy = fixture.get("zone_hierarchy") or {}
|
|
209
|
+
results: list[QueryResult] = []
|
|
210
|
+
|
|
211
|
+
for query in fixture.get("queries", []):
|
|
212
|
+
zone = query.get("zone") or fixture.get("default_zone") or ""
|
|
213
|
+
scope = zones_in_scope(zone, hierarchy) if zone else set()
|
|
214
|
+
|
|
215
|
+
started = time.perf_counter()
|
|
216
|
+
hits = (
|
|
217
|
+
index.search(query["text"], scope, limit=query.get("limit", 5), vocabulary=vocabulary)
|
|
218
|
+
if scope
|
|
219
|
+
else []
|
|
220
|
+
)
|
|
221
|
+
elapsed = (time.perf_counter() - started) * 1000
|
|
222
|
+
|
|
223
|
+
expected = (query.get("expect") or {}).get("documents") or []
|
|
224
|
+
verified = bool((query.get("expect") or {}).get("verified"))
|
|
225
|
+
expected_hit = None
|
|
226
|
+
if expected:
|
|
227
|
+
retrieved = {p.document for _, p in hits}
|
|
228
|
+
expected_hit = any(e in retrieved for e in expected)
|
|
229
|
+
|
|
230
|
+
# Anything returned from outside the permitted scope is a failure of the
|
|
231
|
+
# only guarantee the system makes about where advice applies.
|
|
232
|
+
violations = [p.document for _, p in hits if p.zone not in scope]
|
|
233
|
+
|
|
234
|
+
results.append(
|
|
235
|
+
QueryResult(
|
|
236
|
+
id=query.get("id", "?"),
|
|
237
|
+
question=query["text"],
|
|
238
|
+
found=len(hits),
|
|
239
|
+
top=[{"document": p.document, "zone": p.zone, "tier": p.tier, "chunk": p.id} for _, p in hits[:3]],
|
|
240
|
+
expected_hit=expected_hit,
|
|
241
|
+
boundary_violation=violations,
|
|
242
|
+
elapsed_ms=round(elapsed, 1),
|
|
243
|
+
verified_expectation=verified,
|
|
244
|
+
)
|
|
245
|
+
)
|
|
246
|
+
return results
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def diagnose(passages: list[Passage]) -> list[str]:
|
|
250
|
+
"""Reasons a corpus will answer nothing, stated before the run does.
|
|
251
|
+
|
|
252
|
+
Zone is a hard retrieval boundary, so a corpus ingested without a publisher
|
|
253
|
+
profile carries no zone and every query is refused. That is the boundary
|
|
254
|
+
working — advice that cannot be placed is not served — but the report it
|
|
255
|
+
produces reads as `0 answered, 0 boundary violations`, which looks closer to
|
|
256
|
+
success than to the misconfiguration it is.
|
|
257
|
+
"""
|
|
258
|
+
notes = []
|
|
259
|
+
if not passages:
|
|
260
|
+
return ["the corpus is empty: no passages were loaded from the manifest"]
|
|
261
|
+
|
|
262
|
+
zoneless = sum(1 for p in passages if not p.zone)
|
|
263
|
+
if zoneless == len(passages):
|
|
264
|
+
notes.append(
|
|
265
|
+
f"every one of {len(passages):,} passages has no zone, so every query will be "
|
|
266
|
+
"refused. The corpus was probably ingested without EGREGORE_PUBLISHER_PROFILE set."
|
|
267
|
+
)
|
|
268
|
+
elif zoneless:
|
|
269
|
+
notes.append(f"{zoneless:,} of {len(passages):,} passages have no zone and can never be served")
|
|
270
|
+
|
|
271
|
+
tierless = sum(1 for p in passages if not p.tier)
|
|
272
|
+
if tierless == len(passages):
|
|
273
|
+
notes.append("no passage carries a trust tier, so results cannot be ranked by source reliability")
|
|
274
|
+
return notes
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def report(results: list[QueryResult]) -> dict:
|
|
278
|
+
answered = [r for r in results if r.found]
|
|
279
|
+
checked = [r for r in results if r.expected_hit is not None and r.verified_expectation]
|
|
280
|
+
hits = [r for r in checked if r.expected_hit]
|
|
281
|
+
latencies = sorted(r.elapsed_ms for r in results) or [0.0]
|
|
282
|
+
violations = [r for r in results if r.boundary_violation]
|
|
283
|
+
|
|
284
|
+
def pct(n, d):
|
|
285
|
+
return round(100 * n / d, 1) if d else None
|
|
286
|
+
|
|
287
|
+
return {
|
|
288
|
+
"queries": len(results),
|
|
289
|
+
"answered": len(answered),
|
|
290
|
+
"unanswered": len(results) - len(answered),
|
|
291
|
+
"unanswered_rate_pct": pct(len(results) - len(answered), len(results)),
|
|
292
|
+
"boundary_violations": len(violations),
|
|
293
|
+
"citation_hit_rate_pct": pct(len(hits), len(checked)),
|
|
294
|
+
"expectations_verified": len(checked),
|
|
295
|
+
"expectations_unverified": sum(
|
|
296
|
+
1 for r in results if r.expected_hit is not None and not r.verified_expectation
|
|
297
|
+
),
|
|
298
|
+
"p50_ms": latencies[len(latencies) // 2],
|
|
299
|
+
"p95_ms": latencies[min(len(latencies) - 1, int(len(latencies) * 0.95))],
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
def format_report(report: dict, results: list[QueryResult], verbose: bool = False) -> str:
|
|
304
|
+
lines = [
|
|
305
|
+
f"queries {report['queries']} · answered {report['answered']} · unanswered {report['unanswered']}",
|
|
306
|
+
"",
|
|
307
|
+
f"boundary_violations {report['boundary_violations']}",
|
|
308
|
+
f"citation_hit_rate_pct {report['citation_hit_rate_pct']}",
|
|
309
|
+
f"expectations_verified {report['expectations_verified']}",
|
|
310
|
+
f"expectations_unverified {report['expectations_unverified']}",
|
|
311
|
+
f"p50_ms {report['p50_ms']} · p95_ms {report['p95_ms']}",
|
|
312
|
+
]
|
|
313
|
+
if report["citation_hit_rate_pct"] is None:
|
|
314
|
+
lines += [
|
|
315
|
+
"",
|
|
316
|
+
"The hit rate is unavailable because no expectation has been confirmed by",
|
|
317
|
+
"someone who knows the domain. It is withheld rather than computed from",
|
|
318
|
+
"guesses, which would only measure agreement with whoever wrote the fixture.",
|
|
319
|
+
]
|
|
320
|
+
if verbose:
|
|
321
|
+
lines.append("")
|
|
322
|
+
for r in results:
|
|
323
|
+
lines.append(f"[{r.id}] {r.question}")
|
|
324
|
+
lines.append(f" {r.found} found · {r.elapsed_ms} ms")
|
|
325
|
+
for hit in r.top:
|
|
326
|
+
lines.append(f" · {hit['document'][:70]} ({hit['zone']}, {hit['tier']})")
|
|
327
|
+
if r.boundary_violation:
|
|
328
|
+
lines.append(f" VIOLATION: {r.boundary_violation}")
|
|
329
|
+
return "\n".join(lines)
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
def main(argv: list[str] | None = None) -> int:
|
|
333
|
+
import argparse
|
|
334
|
+
|
|
335
|
+
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
|
336
|
+
parser.add_argument("--fixture", required=True, type=Path)
|
|
337
|
+
parser.add_argument("--manifest", required=True, type=Path)
|
|
338
|
+
parser.add_argument("--data-root", required=True, type=Path)
|
|
339
|
+
parser.add_argument("--vocabulary", type=Path, nargs="*", default=[],
|
|
340
|
+
help="term files used to expand a question into the archive's wording")
|
|
341
|
+
parser.add_argument("--verbose", action="store_true", help="show retrieved sources per query")
|
|
342
|
+
parser.add_argument("--json", action="store_true", help="emit the report as JSON")
|
|
343
|
+
args = parser.parse_args(argv)
|
|
344
|
+
|
|
345
|
+
fixture = json.loads(args.fixture.read_text(encoding="utf-8"))
|
|
346
|
+
started = time.perf_counter()
|
|
347
|
+
passages = load_passages(args.manifest, args.data_root)
|
|
348
|
+
index = Index(passages)
|
|
349
|
+
if not args.json:
|
|
350
|
+
print(f"loaded {len(passages):,} passages in {time.perf_counter() - started:.1f}s "
|
|
351
|
+
"(bibliographies excluded)\n")
|
|
352
|
+
|
|
353
|
+
vocabulary = None
|
|
354
|
+
if args.vocabulary:
|
|
355
|
+
import term_expand
|
|
356
|
+
|
|
357
|
+
vocabulary = term_expand.load_vocabulary(args.vocabulary)
|
|
358
|
+
if not args.json:
|
|
359
|
+
print(f"vocabulary: {len(vocabulary)} term groups")
|
|
360
|
+
for skipped in vocabulary.skipped:
|
|
361
|
+
print(f" skipped {skipped}")
|
|
362
|
+
|
|
363
|
+
problems = diagnose(passages)
|
|
364
|
+
if problems and not args.json:
|
|
365
|
+
for note in problems:
|
|
366
|
+
print(f"!! {note}")
|
|
367
|
+
print()
|
|
368
|
+
|
|
369
|
+
results = run(fixture, index, vocabulary=vocabulary)
|
|
370
|
+
summary = report(results)
|
|
371
|
+
|
|
372
|
+
if args.json:
|
|
373
|
+
print(json.dumps({"report": summary, "diagnostics": problems,
|
|
374
|
+
"results": [vars(r) for r in results]},
|
|
375
|
+
ensure_ascii=False, indent=2))
|
|
376
|
+
else:
|
|
377
|
+
print(format_report(summary, results, verbose=args.verbose))
|
|
378
|
+
|
|
379
|
+
# A boundary violation is the one failure that must be actionable from a
|
|
380
|
+
# script; everything else is a measurement, not a fault.
|
|
381
|
+
return 1 if (summary["boundary_violations"] or problems) else 0
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
if __name__ == "__main__":
|
|
385
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# Resolve the stable Runtime identity before Observe can emit attributed
|
|
5
|
+
# context. Connected instances adopt IDs from the authenticated control plane;
|
|
6
|
+
# legacy Local instances create opaque local IDs once. Network failure remains
|
|
7
|
+
# non-fatal to startup and is retried next session.
|
|
8
|
+
|
|
9
|
+
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
10
|
+
CONFIG="$ROOT/egregore.json"
|
|
11
|
+
STATE="$ROOT/.egregore-state.json"
|
|
12
|
+
|
|
13
|
+
resolved() {
|
|
14
|
+
[ -f "$CONFIG" ] && [ -f "$STATE" ] || return 1
|
|
15
|
+
jq -e '
|
|
16
|
+
(.org_id | type == "string" and length > 0 and (startswith("legacy-org:") | not))
|
|
17
|
+
' "$CONFIG" >/dev/null 2>&1 || return 1
|
|
18
|
+
jq -e '
|
|
19
|
+
[ .account_id, .actor_id, .membership_id ]
|
|
20
|
+
| all(type == "string" and length > 0)
|
|
21
|
+
' "$STATE" >/dev/null 2>&1
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
case "${1:-ensure}" in
|
|
25
|
+
status)
|
|
26
|
+
if resolved; then
|
|
27
|
+
printf '{"status":"resolved"}\n'
|
|
28
|
+
exit 0
|
|
29
|
+
fi
|
|
30
|
+
printf '{"status":"unresolved"}\n'
|
|
31
|
+
exit 1
|
|
32
|
+
;;
|
|
33
|
+
ensure)
|
|
34
|
+
resolved && exit 0
|
|
35
|
+
mode="$(jq -r 'if (.mode // "local") == "connected" or (.api_url // "") != "" then "connected" else "local" end' "$CONFIG" 2>/dev/null || echo local)"
|
|
36
|
+
if [ "$mode" = "local" ]; then
|
|
37
|
+
EGREGORE_ROOT="$ROOT" python3 -m egregore_runtime.identity_cli initialize-local >/dev/null
|
|
38
|
+
else
|
|
39
|
+
api_url="$(jq -r '.api_url // empty' "$CONFIG" 2>/dev/null)"
|
|
40
|
+
api_key="$(grep '^EGREGORE_API_KEY=' "$ROOT/.env" 2>/dev/null | cut -d= -f2-)"
|
|
41
|
+
[ -n "$api_url" ] && [ -n "$api_key" ] || exit 1
|
|
42
|
+
# Identity repair is read-only: select the already-existing account and
|
|
43
|
+
# membership records, then adopt their opaque IDs locally. If migration
|
|
44
|
+
# 038 has not reached the control plane, the next session retries.
|
|
45
|
+
control_plane="$(curl -sf "$api_url/api/org/status" \
|
|
46
|
+
-H "Authorization: Bearer $api_key" --connect-timeout 2 --max-time 4 \
|
|
47
|
+
2>/dev/null || true)"
|
|
48
|
+
printf '%s' "$control_plane" | jq -e \
|
|
49
|
+
'.org_id | type == "string" and length > 0' >/dev/null 2>&1 || exit 1
|
|
50
|
+
slug="$(jq -r '.slug // empty' "$CONFIG" 2>/dev/null)"
|
|
51
|
+
[ -n "$slug" ] || exit 1
|
|
52
|
+
roster="$(curl -sf "$api_url/api/org/$slug/members?include_removed=true" \
|
|
53
|
+
-H "Authorization: Bearer $api_key" --connect-timeout 2 --max-time 4 \
|
|
54
|
+
2>/dev/null || true)"
|
|
55
|
+
printf '%s' "$roster" | jq -e \
|
|
56
|
+
'.members | type == "array"' >/dev/null 2>&1 || exit 1
|
|
57
|
+
jq -cn \
|
|
58
|
+
--argjson organization "$control_plane" \
|
|
59
|
+
--argjson roster "$roster" \
|
|
60
|
+
'{organization:$organization,roster:$roster}' | \
|
|
61
|
+
EGREGORE_ROOT="$ROOT" python3 -m egregore_runtime.identity_cli \
|
|
62
|
+
reconcile-records >/dev/null
|
|
63
|
+
fi
|
|
64
|
+
resolved
|
|
65
|
+
;;
|
|
66
|
+
*)
|
|
67
|
+
echo 'usage: bash bin/runtime-identity.sh {ensure|status}' >&2
|
|
68
|
+
exit 2
|
|
69
|
+
;;
|
|
70
|
+
esac
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# runtime-upgrade.sh — deterministic bridge for the per-instance Runtime
|
|
3
|
+
# upgrade. The launcher's Settings surface and advanced callers drive the
|
|
4
|
+
# transactional engine through these verbs; the Python Runtime owns all
|
|
5
|
+
# state, staging, gates, activation, and rollback. Output is JSON for
|
|
6
|
+
# renderers — this script is an internal surface, not the user experience.
|
|
7
|
+
#
|
|
8
|
+
# Verbs:
|
|
9
|
+
# status [--fetch] durable upgrade + team-sync state
|
|
10
|
+
# init --candidate <ver> stage a candidate (X.Y.Z-runtime-mvp.N only)
|
|
11
|
+
# prepare start/resume the detached preparation worker
|
|
12
|
+
# activate atomic activation; refuses unless every gate passed
|
|
13
|
+
# cancel request cancellation; previous Runtime untouched
|
|
14
|
+
# rollback restore the recorded previous Runtime version
|
|
15
|
+
# team-sync [--fetch] canonical memory sync state only
|
|
16
|
+
set -uo pipefail
|
|
17
|
+
|
|
18
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
19
|
+
|
|
20
|
+
# EGREGORE_INSTANCE_ROOT lets the packaged launcher bridge drive an instance
|
|
21
|
+
# that predates this script: engine code always comes from this script's own
|
|
22
|
+
# tree, while the target instance is set explicitly — never inferred.
|
|
23
|
+
INSTANCE_ROOT="${EGREGORE_INSTANCE_ROOT:-$SCRIPT_DIR}"
|
|
24
|
+
|
|
25
|
+
_runtime() {
|
|
26
|
+
EGREGORE_ROOT="$INSTANCE_ROOT" \
|
|
27
|
+
PYTHONPATH="$SCRIPT_DIR${PYTHONPATH:+:$PYTHONPATH}" \
|
|
28
|
+
python3 -m egregore_runtime.harness_cli "$@"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
case "${1:-}" in
|
|
32
|
+
status) shift; _runtime upgrade status "$@" ;;
|
|
33
|
+
init) shift; _runtime upgrade init "$@" ;;
|
|
34
|
+
prepare) shift; _runtime upgrade prepare "$@" ;;
|
|
35
|
+
activate) shift; _runtime upgrade activate "$@" ;;
|
|
36
|
+
cancel) shift; _runtime upgrade cancel "$@" ;;
|
|
37
|
+
rollback) shift; _runtime upgrade rollback "$@" ;;
|
|
38
|
+
team-sync) shift; _runtime team-sync "$@" ;;
|
|
39
|
+
*)
|
|
40
|
+
echo "usage: bash bin/runtime-upgrade.sh {status|init --candidate <version>|prepare|activate|cancel|rollback|team-sync}" >&2
|
|
41
|
+
exit 2
|
|
42
|
+
;;
|
|
43
|
+
esac
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
5
|
+
export EGREGORE_ROOT="$ROOT"
|
|
6
|
+
export EGREGORE_SESSION_ID="${EGREGORE_SESSION_ID:-$(cat "$ROOT/.egregore-session-id" 2>/dev/null || true)}"
|
|
7
|
+
export PYTHONPATH="$ROOT${PYTHONPATH:+:$PYTHONPATH}"
|
|
8
|
+
|
|
9
|
+
exec python3 -m egregore_runtime.scroll_cli "$@"
|