ctx-lessons 0.1.0__tar.gz

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.
Files changed (88) hide show
  1. ctx_lessons-0.1.0/.claude/skills/aidlc/SKILL.md +162 -0
  2. ctx_lessons-0.1.0/.claude/skills/aidlc/TEMPLATES/slice-aidlc-state.md +41 -0
  3. ctx_lessons-0.1.0/.claude/skills/aidlc/TEMPLATES/slice-audit.md +17 -0
  4. ctx_lessons-0.1.0/.github/workflows/ci.yml +34 -0
  5. ctx_lessons-0.1.0/.github/workflows/release.yml +81 -0
  6. ctx_lessons-0.1.0/.gitignore +23 -0
  7. ctx_lessons-0.1.0/CONTEXT.md +43 -0
  8. ctx_lessons-0.1.0/LICENSE +21 -0
  9. ctx_lessons-0.1.0/PKG-INFO +252 -0
  10. ctx_lessons-0.1.0/README.md +224 -0
  11. ctx_lessons-0.1.0/pyproject.toml +73 -0
  12. ctx_lessons-0.1.0/src/ctx/__init__.py +0 -0
  13. ctx_lessons-0.1.0/src/ctx/cli/__init__.py +0 -0
  14. ctx_lessons-0.1.0/src/ctx/cli/app.py +66 -0
  15. ctx_lessons-0.1.0/src/ctx/cli/config.py +226 -0
  16. ctx_lessons-0.1.0/src/ctx/cli/init.py +123 -0
  17. ctx_lessons-0.1.0/src/ctx/db/__init__.py +38 -0
  18. ctx_lessons-0.1.0/src/ctx/db/migrations.py +27 -0
  19. ctx_lessons-0.1.0/src/ctx/db/queries.py +219 -0
  20. ctx_lessons-0.1.0/src/ctx/db/schema.py +59 -0
  21. ctx_lessons-0.1.0/src/ctx/ingest/__init__.py +0 -0
  22. ctx_lessons-0.1.0/src/ctx/ingest/commands.py +295 -0
  23. ctx_lessons-0.1.0/src/ctx/ingest/cursor.py +38 -0
  24. ctx_lessons-0.1.0/src/ctx/ingest/docs.py +109 -0
  25. ctx_lessons-0.1.0/src/ctx/ingest/extract.py +210 -0
  26. ctx_lessons-0.1.0/src/ctx/ingest/filters.py +45 -0
  27. ctx_lessons-0.1.0/src/ctx/ingest/gh.py +116 -0
  28. ctx_lessons-0.1.0/src/ctx/lesson/__init__.py +0 -0
  29. ctx_lessons-0.1.0/src/ctx/lesson/commands.py +167 -0
  30. ctx_lessons-0.1.0/src/ctx/lesson/frontmatter.py +46 -0
  31. ctx_lessons-0.1.0/src/ctx/lesson/models.py +68 -0
  32. ctx_lessons-0.1.0/src/ctx/lesson/transitions.py +28 -0
  33. ctx_lessons-0.1.0/src/ctx/paths.py +25 -0
  34. ctx_lessons-0.1.0/src/ctx/promote/__init__.py +0 -0
  35. ctx_lessons-0.1.0/src/ctx/promote/commands.py +94 -0
  36. ctx_lessons-0.1.0/src/ctx/promote/git_ops.py +95 -0
  37. ctx_lessons-0.1.0/src/ctx/promote/pr_body.py +45 -0
  38. ctx_lessons-0.1.0/src/ctx/promote/validate.py +59 -0
  39. ctx_lessons-0.1.0/src/ctx/py.typed +0 -0
  40. ctx_lessons-0.1.0/src/ctx/query/__init__.py +0 -0
  41. ctx_lessons-0.1.0/src/ctx/query/commands.py +215 -0
  42. ctx_lessons-0.1.0/src/ctx/query/formatting.py +168 -0
  43. ctx_lessons-0.1.0/src/ctx/query/ranking.py +40 -0
  44. ctx_lessons-0.1.0/src/ctx/query/search.py +66 -0
  45. ctx_lessons-0.1.0/src/ctx/session.py +23 -0
  46. ctx_lessons-0.1.0/src/ctx/sync/__init__.py +0 -0
  47. ctx_lessons-0.1.0/src/ctx/sync/commands.py +50 -0
  48. ctx_lessons-0.1.0/src/ctx/sync/sync.py +154 -0
  49. ctx_lessons-0.1.0/src/ctx/sync/team_knowledge.py +70 -0
  50. ctx_lessons-0.1.0/tests/__init__.py +0 -0
  51. ctx_lessons-0.1.0/tests/cli/__init__.py +0 -0
  52. ctx_lessons-0.1.0/tests/cli/test_config.py +236 -0
  53. ctx_lessons-0.1.0/tests/cli/test_init.py +118 -0
  54. ctx_lessons-0.1.0/tests/cli/test_root.py +25 -0
  55. ctx_lessons-0.1.0/tests/db/__init__.py +0 -0
  56. ctx_lessons-0.1.0/tests/db/conftest.py +41 -0
  57. ctx_lessons-0.1.0/tests/db/test_lifecycle.py +70 -0
  58. ctx_lessons-0.1.0/tests/db/test_migrations.py +91 -0
  59. ctx_lessons-0.1.0/tests/db/test_roundtrip.py +81 -0
  60. ctx_lessons-0.1.0/tests/db/test_search.py +174 -0
  61. ctx_lessons-0.1.0/tests/ingest/__init__.py +0 -0
  62. ctx_lessons-0.1.0/tests/ingest/test_cursor.py +20 -0
  63. ctx_lessons-0.1.0/tests/ingest/test_doc_cmd.py +214 -0
  64. ctx_lessons-0.1.0/tests/ingest/test_docs.py +113 -0
  65. ctx_lessons-0.1.0/tests/ingest/test_extract.py +113 -0
  66. ctx_lessons-0.1.0/tests/ingest/test_filters.py +90 -0
  67. ctx_lessons-0.1.0/tests/ingest/test_gh.py +75 -0
  68. ctx_lessons-0.1.0/tests/ingest/test_ingest_cmd.py +210 -0
  69. ctx_lessons-0.1.0/tests/lesson/__init__.py +0 -0
  70. ctx_lessons-0.1.0/tests/lesson/test_commands.py +343 -0
  71. ctx_lessons-0.1.0/tests/lesson/test_frontmatter.py +99 -0
  72. ctx_lessons-0.1.0/tests/lesson/test_models.py +175 -0
  73. ctx_lessons-0.1.0/tests/lesson/test_transitions.py +81 -0
  74. ctx_lessons-0.1.0/tests/promote/__init__.py +0 -0
  75. ctx_lessons-0.1.0/tests/promote/test_pr_body.py +74 -0
  76. ctx_lessons-0.1.0/tests/promote/test_promote_cmd.py +272 -0
  77. ctx_lessons-0.1.0/tests/promote/test_validate.py +88 -0
  78. ctx_lessons-0.1.0/tests/query/__init__.py +0 -0
  79. ctx_lessons-0.1.0/tests/query/conftest.py +84 -0
  80. ctx_lessons-0.1.0/tests/query/snapshots/search_json.json +24 -0
  81. ctx_lessons-0.1.0/tests/query/snapshots/search_text.txt +9 -0
  82. ctx_lessons-0.1.0/tests/query/test_formatting.py +92 -0
  83. ctx_lessons-0.1.0/tests/query/test_ranking.py +135 -0
  84. ctx_lessons-0.1.0/tests/query/test_search_cmd.py +367 -0
  85. ctx_lessons-0.1.0/tests/sync/__init__.py +0 -0
  86. ctx_lessons-0.1.0/tests/sync/test_sync.py +230 -0
  87. ctx_lessons-0.1.0/tests/sync/test_team_knowledge.py +150 -0
  88. ctx_lessons-0.1.0/uv.lock +507 -0
@@ -0,0 +1,162 @@
1
+ ---
2
+ name: aidlc
3
+ description: Drive a unit of work through the AI Development Lifecycle. Use when the user says "/aidlc", asks to start a slice / epic / new feature, asks to pick up a queued issue, or says anything like "let's do AI-DLC on X", "start inception for X", "move X to construction", "scaffold a slice for X". Also use to log out-of-band chore work into the project audit trail.
4
+ ---
5
+
6
+ # AI-DLC
7
+
8
+ Drives work through the AI Development Lifecycle. This skill is the executable wrapper: triage the request, scaffold the right artefacts, walk the right stages, keep the audit trail honest.
9
+
10
+ The process follows the AWS canvas (`awslabs/aidlc-workflows`), adapted with TDD, vertical slices, and brownfield reverse engineering where needed. When in doubt: phase names, ALWAYS/CONDITIONAL, FD-before-NFR, TG-before-CG are load-bearing.
11
+
12
+ ## Reference docs
13
+
14
+ - `TEMPLATES/` (this skill) — copy-ready scaffolds for slice folders and audit entries
15
+ - `aidlc-docs/<slice>/audit.md` — append-only log of AI decisions + user approvals for that slice
16
+ - `aidlc-docs/<slice>/aidlc-state.md` — current phase/stage progress for that slice
17
+
18
+ No project-wide tracker. Audit and state live **only** under the slice they belong to. Recipe and chore work do not get audit entries — trust `git log` and PR descriptions.
19
+
20
+ ## Triage — pick the right process
21
+
22
+ Three flavours of work. **Pick before scaffolding anything.**
23
+
24
+ | Flavour | When to use | Process |
25
+ |---|---|---|
26
+ | **Greenfield slice** | New feature with non-obvious requirements, non-trivial design space, multiple units of work. | Full AI-DLC: scaffold `aidlc-docs/<slice>/`, run Inception → Construction with all artefacts, gated `[Answer]:` plans at each stage. **TG-as-RED is mandatory** — tests are written first, then code. Review Gate runs pre-PR. |
27
+ | **Recipe / sweep** | Mechanical work following a known pattern. | Light: append one audit entry at start ("CONSTRUCTION - Code Generation"), execute, append one at end ("Build and Test"). No per-slice folder. Skip TG-as-RED (work is mechanical); still run `security-review` + `simplify` as a mini Review Gate before PR. |
28
+ | **Chore / infra / ops** | Repo restructure, CI tweaks, doc migration, branch cleanup. No slice equivalent. | Minimal: single audit entry on completion. No per-slice folder, no state-file slice rows. No TG, no Review Gate. May still create issues for tracking. |
29
+
30
+ If unsure, ask the user. Don't auto-promote a recipe to a greenfield slice — that wastes inception cycles.
31
+
32
+ ## Greenfield slice — the full path
33
+
34
+ ### 1. Inception
35
+
36
+ Create the slice scaffold:
37
+
38
+ ```bash
39
+ SLICE=<snake_case_feature_name> # should match code structure where applicable
40
+ mkdir -p aidlc-docs/$SLICE/{inception/{plans,reverse-engineering,user-stories,application-design},construction}
41
+ cp .claude/skills/aidlc/TEMPLATES/slice-audit.md aidlc-docs/$SLICE/audit.md
42
+ cp .claude/skills/aidlc/TEMPLATES/slice-aidlc-state.md aidlc-docs/$SLICE/aidlc-state.md
43
+ # Replace <SLICE> placeholder in both files with $SLICE
44
+ sed -i '' "s|<SLICE>|$SLICE|g" aidlc-docs/$SLICE/audit.md aidlc-docs/$SLICE/aidlc-state.md
45
+ ```
46
+
47
+ Inception stages, in canvas order. ALWAYS stages run every slice; CONDITIONAL stages run when they add value. Each stage produces a plan with `[Answer]:` tags first (where listed), gets user confirmation, then produces the artefact:
48
+
49
+ | # | Stage | Freq | Plan file | Artefact |
50
+ |---|---|---|---|---|
51
+ | 1 | Workspace Detection | ALWAYS | *(automatic, no plan)* | `inception/workspace-detection.md` |
52
+ | 2 | Reverse Engineering | CONDITIONAL (brownfield) | `inception/plans/reverse-engineering-plan.md` | `inception/reverse-engineering/{code-structure,domain-model,integration-map}.md` |
53
+ | 3 | Requirements Analysis | ALWAYS | `inception/plans/requirements-analysis-plan.md` | `inception/requirements-analysis.md` |
54
+ | 4 | User Stories | CONDITIONAL | `inception/plans/story-generation-plan.md` | `inception/user-stories/{stories,personas}.md` |
55
+ | 5 | Application Design (DDD) | CONDITIONAL | `inception/plans/application-design-plan.md` | `inception/application-design/{unit-of-work,unit-of-work-dependency,unit-of-work-story-map}.md` |
56
+ | 6 | Units Generation (vertical slices) | CONDITIONAL | `inception/plans/units-generation-plan.md` | Work units defined, tracking issues created (optional) |
57
+ | 7 | Workflow Planning | ALWAYS | `inception/plans/workflow-planning-plan.md` | `inception/workflow-planning.md` — names which Construction stages run per unit |
58
+
59
+ Most work is brownfield. Reverse Engineering runs for any slice touching existing code — that's nearly every slice. Skip it only for slices creating wholly new modules with no overlap.
60
+
61
+ At end of inception:
62
+ - All inception-gate checkboxes ticked in `aidlc-docs/<slice>/aidlc-state.md`
63
+ - Any tracking issues created (optional, per project preference)
64
+ - All work units identified and sequenced
65
+
66
+ ### 2. Construction
67
+
68
+ For each unit of work, in dependency order. **Canvas stage order — do not reorder.** FD before NFR is load-bearing; TG (RED) before CG (GREEN) is non-negotiable.
69
+
70
+ | # | Stage | Freq | TDD | Artefact |
71
+ |---|---|---|---|---|
72
+ | 1 | Functional Design | CONDITIONAL | — | `construction/functional-design.md` — business logic per unit |
73
+ | 2 | NFR Requirements | CONDITIONAL | — | `construction/nfr-requirements.md` — NFRs + tech stack |
74
+ | 3 | NFR Design | CONDITIONAL | — | `construction/nfr-design.md` |
75
+ | 4 | Infrastructure Design | CONDITIONAL | — | `construction/infrastructure-design.md` |
76
+ | 5 | **Test Generation** | **ALWAYS** | **RED** | `construction/test-generation.md` + failing tests on branch |
77
+ | 6 | **Code Generation** | **ALWAYS** | **GREEN + REFACTOR** | minimal code to pass tests, then refactor; tests green |
78
+ | 7 | Build and Test | ALWAYS | — | full suite green (integration + e2e where applicable) |
79
+ | 8 | **Review Gate** | ALWAYS | — | `construction/review-gate.md` — parallel review battery passes; advisory findings filed as follow-up issues |
80
+ | 9 | PR Merged | ALWAYS | — | PR opened with `review-gate.md` linked, merged, Task issue closed |
81
+
82
+ Track work progress through stages: `Ready → In Development → In Review → Completed`. `In Review` is set only after the **Review Gate** passes and the PR is opened.
83
+
84
+ ### Review Gate (mandatory pre-PR)
85
+
86
+ See [`docs/agents/aidlc.md`](../../../docs/agents/aidlc.md#review-gate) for the full spec. Quick reference:
87
+
88
+ - **Run in parallel**, after local tests pass, before `gh pr create`.
89
+ - **Greenfield:** `security-review`, `simplify`, and an agent-driven **correctness pass** against `stories.md` + `functional-design.md`.
90
+ - **Recipe:** `security-review` + `simplify` only.
91
+ - **Chore:** skip entirely.
92
+ - **Never invoke `/ultrareview`** — user-triggered only. Recommend it for auth/payments/PII slices; don't launch it.
93
+
94
+ **Blocking** (PR does not open until fixed):
95
+ - `security-review` HIGH/CRITICAL
96
+ - Correctness pass finds an unmet acceptance criterion
97
+
98
+ **Advisory** (file follow-up issue, do NOT fix in this PR — prevents scope sprawl):
99
+ - `simplify` findings
100
+ - Test-quality advisories
101
+
102
+ Write `aidlc-docs/<slice>/construction/review-gate.md` with verdicts, follow-up issue numbers, and re-run history. Link it in the PR description. For recipes, append the gate block to the recipe's audit entry instead of creating a slice folder.
103
+
104
+ ### 3. Documentation pass
105
+
106
+ When the slice closes, update any relevant project documentation with learnings from the slice. This might include:
107
+ - Updating CONTEXT.md with new terminology or domain clarifications
108
+ - Recording decisions in a project ADR if they affect architecture
109
+ - Updating README.md with new features or changed behavior
110
+
111
+ ## Recipe / sweep — the light path
112
+
113
+ No slice folder, no audit entry. Do the work, ship the PR, write a clear commit message + PR description. `git log` is the record.
114
+
115
+ ## Chore / infra — minimal
116
+
117
+ Same as recipe: no slice folder, no audit. Commit message + PR description carries the why.
118
+
119
+ ## Audit-log schema (per-slice `aidlc-docs/<slice>/audit.md`)
120
+
121
+ Greenfield slices keep an append-only audit trail. Each entry:
122
+
123
+ ```markdown
124
+ ---
125
+
126
+ ## <STAGE> - <short description>
127
+ **Timestamp**: <ISO-8601 UTC>
128
+ **User Input**: "<verbatim or summarised user request>"
129
+ **AI Response**: "<what you did, terse, decision-focused>"
130
+ **Context**: <one-line note>
131
+
132
+ [optional]
133
+ **Process note**: <why this entry exists out of normal AI-DLC flow>
134
+
135
+ ---
136
+ ```
137
+
138
+ `<STAGE>` is one of: `INCEPTION - <stage>`, `CONSTRUCTION - <stage>`.
139
+
140
+ ## State-file update rules
141
+
142
+ `aidlc-docs/<slice>/aidlc-state.md` — checkboxes for the slice's own stages. Greenfield only. Update at the same commit as the artefact it represents — never split.
143
+
144
+ ## Invocation patterns
145
+
146
+ - `/aidlc` (no args) — show current state: scan `aidlc-docs/*/aidlc-state.md` for the active slices' current stages; suggest next pickups from open issues.
147
+ - `/aidlc start <slice-name>` or "start AI-DLC on the auth slice" — triage, scaffold if greenfield, begin Inception stage 1.
148
+ - `/aidlc continue` or "continue the auth slice" — read the slice's `aidlc-state.md`, identify the next unchecked stage, resume there.
149
+ - `/aidlc close <slice>` — verify all task issues closed, kick off living-docs pass, mark slice complete in `aidlc-docs/<slice>/aidlc-state.md`.
150
+
151
+ ## When NOT to use this skill
152
+
153
+ - Bug-fix PRs not tied to a slice → use `diagnose` or `triage-issue`.
154
+ - Creating issues from scratch → use `to-issues` or `to-prd` first; this skill picks up after the epic exists.
155
+ - VS Code config tweaks, dependency bumps → just do it. Don't manufacture an audit entry for noise.
156
+
157
+ ## Discipline reminders
158
+
159
+ - `audit.md` is **append-only**. Never edit past entries — add a follow-up entry if a decision is reversed.
160
+ - PiT records in `aidlc-docs/<slice>/` are **frozen at slice close**. Corrections go to the wiki, not back into the slice folder.
161
+ - Plans use `[Answer]: <maintainer's answer>` tags so the human gate is preserved in the artefact.
162
+ - Snake_case slice names should match code structure and be consistent across artefacts.
@@ -0,0 +1,41 @@
1
+ # <SLICE> — AI-DLC state
2
+
3
+ ## Slice info
4
+ - **Slice name**: `<SLICE>`
5
+ - **Issue tracking**: *(if using GitHub/Linear/etc, link here)*
6
+ - **Design doc**: `docs/<SLICE>.md` or inline in audit.md *(if applicable)*
7
+ - **Status**: Inception — not started
8
+ - **Blocker**: None
9
+
10
+ ## Inception
11
+ - [ ] Workspace detection — artefact
12
+ - [ ] Reverse engineering — artefact *(if touching existing code)*
13
+ - [ ] Requirements analysis — plan
14
+ - [ ] Requirements analysis — artefact
15
+ - [ ] Story generation — plan
16
+ - [ ] Story generation — artefact
17
+ - [ ] Workflow planning — plan
18
+ - [ ] Workflow planning — artefact
19
+ - [ ] Application design — plan
20
+ - [ ] Application design — artefact (unit-of-work + dependency + story-map)
21
+ - [ ] Units generation — plan
22
+ - [ ] Units generation — work units defined and sequenced
23
+
24
+ ## Construction
25
+ *(populate one block per unit of work after units-generation completes)*
26
+
27
+ ### Unit: <unit-name>
28
+ - [ ] Functional Design *(if needed)*
29
+ - [ ] NFR Requirements *(if needed)*
30
+ - [ ] NFR Design *(if needed)*
31
+ - [ ] Infrastructure Design *(if applicable)*
32
+ - [ ] Test Generation (RED)
33
+ - [ ] Code Generation (GREEN)
34
+ - [ ] Build and Test
35
+ - [ ] Review Gate pass
36
+ - [ ] PR merged
37
+
38
+ ## Slice close
39
+ - [ ] All work units completed
40
+ - [ ] Documentation updated with slice learnings
41
+ - [ ] Slice marked complete in this state file
@@ -0,0 +1,17 @@
1
+ # <SLICE> — AI-DLC audit log
2
+
3
+ Append-only log of AI decisions and user approvals for the `<SLICE>` slice. Never edit past entries — add a follow-up entry if a decision is reversed or refined.
4
+
5
+ Entry schema:
6
+
7
+ ```
8
+ ---
9
+
10
+ ## <STAGE> - <slice>
11
+ **Timestamp**: <ISO-8601 UTC>
12
+ **User Input**: "..."
13
+ **AI Response**: "..."
14
+ **Context**: ...
15
+
16
+ ---
17
+ ```
@@ -0,0 +1,34 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ workflow_call: # allows the release workflow to reuse this as a gate
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ python-version: ["3.12", "3.13"]
16
+ steps:
17
+ - uses: actions/checkout@v5
18
+
19
+ - name: Install uv
20
+ uses: astral-sh/setup-uv@v7
21
+ with:
22
+ enable-cache: true
23
+
24
+ - name: Sync dependencies
25
+ run: uv sync --all-extras --dev --python ${{ matrix.python-version }}
26
+
27
+ - name: Lint
28
+ run: uv run ruff check .
29
+
30
+ - name: Format check
31
+ run: uv run ruff format --check .
32
+
33
+ - name: Test
34
+ run: uv run pytest
@@ -0,0 +1,81 @@
1
+ name: Release
2
+
3
+ # Publishes the `ctx-lessons` distribution (installs the `ctx` command).
4
+ #
5
+ # Two paths:
6
+ # * push a tag `vX.Y.Z` -> builds, gates on CI, publishes to PyPI
7
+ # * manual dispatch -> builds and publishes to TestPyPI for a dry run
8
+ #
9
+ # Auth is PyPI Trusted Publishing (OIDC) — no API tokens stored in this repo.
10
+ # Requires a pending publisher configured at
11
+ # https://pypi.org/manage/account/publishing/ for repo brandonajlowe/ctx-engine,
12
+ # workflow `release.yml`, environment `pypi` (and `testpypi` for the dry run).
13
+
14
+ on:
15
+ push:
16
+ tags: ["v*"]
17
+ workflow_dispatch:
18
+
19
+ jobs:
20
+ ci:
21
+ uses: ./.github/workflows/ci.yml
22
+
23
+ build:
24
+ needs: ci
25
+ runs-on: ubuntu-latest
26
+ steps:
27
+ - uses: actions/checkout@v5
28
+
29
+ - name: Install uv
30
+ uses: astral-sh/setup-uv@v7
31
+
32
+ - name: Check tag matches project version
33
+ if: startsWith(github.ref, 'refs/tags/v')
34
+ run: |
35
+ tag="${GITHUB_REF_NAME#v}"
36
+ project="$(uv version --short)"
37
+ if [ "$tag" != "$project" ]; then
38
+ echo "::error::tag v$tag does not match pyproject version $project"
39
+ exit 1
40
+ fi
41
+
42
+ - name: Build sdist and wheel
43
+ run: uv build
44
+
45
+ - name: Smoke-test the built wheel
46
+ run: uvx --from ./dist/*.whl ctx --version
47
+
48
+ - uses: actions/upload-artifact@v4
49
+ with:
50
+ name: dist
51
+ path: dist/
52
+
53
+ publish-testpypi:
54
+ if: github.event_name == 'workflow_dispatch'
55
+ needs: build
56
+ runs-on: ubuntu-latest
57
+ environment: testpypi
58
+ permissions:
59
+ id-token: write
60
+ steps:
61
+ - uses: actions/download-artifact@v5
62
+ with:
63
+ name: dist
64
+ path: dist/
65
+ - uses: pypa/gh-action-pypi-publish@release/v1
66
+ with:
67
+ repository-url: https://test.pypi.org/legacy/
68
+
69
+ publish-pypi:
70
+ if: startsWith(github.ref, 'refs/tags/v')
71
+ needs: build
72
+ runs-on: ubuntu-latest
73
+ environment: pypi
74
+ permissions:
75
+ id-token: write
76
+ steps:
77
+ - uses: actions/download-artifact@v5
78
+ with:
79
+ name: dist
80
+ path: dist/
81
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,23 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .pytest_cache/
6
+ .ruff_cache/
7
+
8
+ # venv
9
+ .venv/
10
+ .python-version
11
+
12
+ # build
13
+ dist/
14
+ build/
15
+
16
+ # editor
17
+ .vscode/
18
+ .idea/
19
+ *.swp
20
+ .DS_Store
21
+
22
+ # test artefacts pointing at ~/.ctx
23
+ tmp/
@@ -0,0 +1,43 @@
1
+ # CONTEXT — `ctx` glossary
2
+
3
+ Canonical terms used across PRD, AIDLC artefacts, code, and lesson frontmatter. Locked at Requirements Analysis. Any addition or rename goes through an audit-entry-tagged ADR.
4
+
5
+ ## Actors
6
+
7
+ - **developer** — the human running `ctx` from their terminal or inside an AI coding session. Always the principal; `ctx` has no other end-user.
8
+ - **agent** — the AI coding assistant (Claude Code, Codex CLI, Cursor, etc.) that invokes `ctx` as a subprocess. The agent is a *consumer*, not a *principal*: it acts on behalf of the developer.
9
+ - **curator** (also: **lesson librarian**) — a developer wearing the review hat: reviews promotion PRs, runs periodic re-validation, marks lessons deprecated. Not a separate role; a rotating responsibility.
10
+
11
+ ## Domain nouns
12
+
13
+ - **lesson** — the canonical artefact. A markdown file with YAML frontmatter, stored in the team-knowledge repo. One lesson = one curated insight.
14
+ - **candidate** — an LLM-extracted draft lesson that has not yet been promoted. Lives in the personal layer with status `draft` or `imported-pending-review`.
15
+ - **corpus** — the full set of lessons reachable from the local SQLite index (team layer ∪ personal layer).
16
+ - **team-knowledge repo** — the upstream git repo containing the active (curated) lessons. One repo per team in v1.
17
+ - **team layer** — the developer's local clone of the team-knowledge repo at `~/.ctx/team/`.
18
+ - **personal layer** — the developer's local-only draft store at `~/.ctx/personal/`. Never synced anywhere.
19
+ - **draft layer** — synonym for personal layer when referring to lesson lifecycle stage.
20
+ - **scope** — a lesson's reach. One of `org`, `team:<name>`, `product:<name>`, `project:<name>`. Forms a precedence hierarchy: project > team > org for ranking ties.
21
+ - **provenance** — the `source` block on a lesson (`type`, `ref`, `thread_id`). Tells the agent where the lesson came from.
22
+ - **freshness** — derived signal from `created` + `last_reviewed`. Used for ranking decay and for the `ctx stale` query.
23
+ - **supersession** — the relationship between a deprecated lesson and its replacement, expressed via `superseded_by` on the deprecated lesson.
24
+
25
+ ## Process verbs
26
+
27
+ - **ingest** — fetch raw input from a source (GitHub PR threads via `gh`, documents from disk). No filtering, no LLM. Produces a stream of normalised raw items.
28
+ - **filter** — pure-function pre-LLM gating: bot detection, resolution check, substantive-discussion check. Returns boolean or score. No I/O.
29
+ - **extract** — LLM-driven lesson candidate generation. Reads filtered raw items, returns a list of candidate lessons per item. Empty list = no signal.
30
+ - **promote** — open a PR against the team-knowledge repo's `main` branch, moving a draft lesson into the team layer. The PR is the human curation gate.
31
+ - **deprecate** — mark a lesson superseded. Never delete; supersession history is auditable.
32
+ - **supersede** — point a deprecated lesson at its replacement via `superseded_by`.
33
+ - **sync** — `git pull` on `~/.ctx/team/`, then rebuild the SQLite index from team + personal layers.
34
+
35
+ ## Predecessor product
36
+
37
+ The legacy product whose BR / NFR / decision documents seed the corpus. Scope string: **`product:<predecessor-name>`** — final name TBD by maintainer; tracked as the only `[Answer — needs-user-input]` from Requirements Analysis. Update this glossary entry once decided.
38
+
39
+ ## Out of glossary
40
+
41
+ - *user* — ambiguous; use **developer** for the human, **agent** for the AI.
42
+ - *memory* — implies auto-capture; `ctx` is curated, not a memory store. Use **lesson** or **corpus**.
43
+ - *FAQ* — connotation of stale, accumulating noise; `ctx` is designed against this failure mode.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Brandon Lowe
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.