margi 0.1.0__py3-none-any.whl
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.
- margi/__init__.py +3 -0
- margi/__main__.py +3 -0
- margi/_bundled/AGENTS.md +20 -0
- margi/_bundled/skills/margi/SKILL.md +64 -0
- margi/_bundled/skills/margi/commands/grade.md +58 -0
- margi/_bundled/skills/margi/commands/read.md +38 -0
- margi/_bundled/skills/margi/commands/todos.md +66 -0
- margi/_bundled/skills/margi/rubrics/default/alignment.md +11 -0
- margi/_bundled/skills/margi/rubrics/default/argument.md +10 -0
- margi/_bundled/skills/margi/rubrics/default/evidence.md +10 -0
- margi/_bundled/skills/margi/rubrics/default/method.md +11 -0
- margi/_bundled/skills/margi/rubrics/default/rubric.yml +38 -0
- margi/_bundled/skills/margi/rubrics/default/scholarship.md +10 -0
- margi/_bundled/skills/margi/rubrics/default/structure.md +10 -0
- margi/_bundled/skills/margi/rubrics/default/style.md +10 -0
- margi/_bundled/skills/margi/schema/feedback.schema.json +169 -0
- margi/_bundled/skills/margi-challenge/SKILL.md +58 -0
- margi/_bundled/skills/margi-challenge/lenses.md +35 -0
- margi/_bundled/skills/margi-onboard/SKILL.md +76 -0
- margi/_bundled/skills/margi-onboard/interview.md +36 -0
- margi/_bundled/skills/margi-onboard/templates/CHANGELOG.md +3 -0
- margi/_bundled/skills/margi-onboard/templates/constraints.md +15 -0
- margi/_bundled/skills/margi-onboard/templates/dataset.md +21 -0
- margi/_bundled/skills/margi-onboard/templates/field.md +15 -0
- margi/_bundled/skills/margi-onboard/templates/method.md +18 -0
- margi/_bundled/skills/margi-onboard/templates/open-questions.md +3 -0
- margi/_bundled/skills/margi-onboard/templates/research-question.md +21 -0
- margi/_bundled/skills/margi-onboard/templates/structure.md +24 -0
- margi/_bundled/templates/claude-settings.json +25 -0
- margi/_bundled/templates/commit-msg +14 -0
- margi/_bundled/templates/margi-README.md +13 -0
- margi/_bundled/templates/margi-guard.yml +25 -0
- margi/_bundled/templates/thesis.config.yml +32 -0
- margi/adapters/__init__.py +17 -0
- margi/adapters/base.py +85 -0
- margi/adapters/typst.py +198 -0
- margi/cli.py +264 -0
- margi/config.py +69 -0
- margi/docs_check.py +82 -0
- margi/finalize.py +286 -0
- margi/gitutil.py +104 -0
- margi/guard.py +106 -0
- margi/init.py +157 -0
- margi/outline.py +155 -0
- margi/pdf.py +45 -0
- margi/resources.py +31 -0
- margi/schema.py +25 -0
- margi/status.py +76 -0
- margi/todos_sync.py +110 -0
- margi/wrapper.py +125 -0
- margi-0.1.0.dist-info/METADATA +108 -0
- margi-0.1.0.dist-info/RECORD +55 -0
- margi-0.1.0.dist-info/WHEEL +4 -0
- margi-0.1.0.dist-info/entry_points.txt +2 -0
- margi-0.1.0.dist-info/licenses/LICENSE +21 -0
margi/__init__.py
ADDED
margi/__main__.py
ADDED
margi/_bundled/AGENTS.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
## margi rules (AI feedback layer for this thesis)
|
|
2
|
+
|
|
3
|
+
This repository contains a thesis written **entirely by a human**. AI agents working here
|
|
4
|
+
through margi skills give feedback in the margins; they never write the text.
|
|
5
|
+
|
|
6
|
+
1. **Never edit anything outside `margi/`.** No thesis source (`*.typ`, `*.bib`, figures, …),
|
|
7
|
+
no config, no README. Read anything; write only to `margi/docs/`, `margi/todos/` and
|
|
8
|
+
`margi/.staging/`.
|
|
9
|
+
2. **Never write thesis prose.** Comments name the problem and why it matters ("the argument
|
|
10
|
+
in §2.1 assumes X without evidence"). They never contain replacement sentences,
|
|
11
|
+
rewritten paragraphs, or "you could write: …".
|
|
12
|
+
3. **Never write provenance.** Do not add timestamps, SHAs, hashes or model ids to drafts.
|
|
13
|
+
`margi finalize` injects them.
|
|
14
|
+
4. **`margi/feedback/` is append-only.** Never modify or delete existing records.
|
|
15
|
+
5. **Never commit, push, reset or checkout.** `margi finalize` commits margi/ as the margi
|
|
16
|
+
bot. Human work and margi work are never mixed in one commit.
|
|
17
|
+
6. **Don't invent facts about the project.** Everything in `margi/docs/` cites a source file
|
|
18
|
+
and line range or the date the user said it in an interview. Unknown → `open-questions.md`.
|
|
19
|
+
7. **Start every run with `margi finalize --check`** and stop if it fails. End every run with
|
|
20
|
+
`margi finalize`.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: margi
|
|
3
|
+
description: AI feedback in the margins of a human-written thesis. Use for /margi grade, read, todos, outline, status, onboard and challenge. Writes only to margi/ and never writes thesis text.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# margi
|
|
7
|
+
|
|
8
|
+
You are margi, a critical, careful reader of a thesis that a human writes **entirely by
|
|
9
|
+
hand**. You give feedback in the margins. You never write the text.
|
|
10
|
+
|
|
11
|
+
## Hard rules (always)
|
|
12
|
+
|
|
13
|
+
- Read anything. **Write only inside `margi/`**: `margi/.staging/`, `margi/docs/`, `margi/todos/`.
|
|
14
|
+
- **Never write thesis prose.** Say what is wrong and why, never "rewrite as …".
|
|
15
|
+
- **Never write provenance** (timestamps, SHAs, hashes, model ids). Scripts add it.
|
|
16
|
+
- Never modify existing files in `margi/feedback/`. Never run `git commit`/`push`/`reset`/`checkout`.
|
|
17
|
+
- See `../../../AGENTS.md` (repo root) if present. Its margi section is authoritative.
|
|
18
|
+
|
|
19
|
+
## Every run
|
|
20
|
+
|
|
21
|
+
1. Run `margi finalize --check`. If it fails, show the message and **stop**. The user must
|
|
22
|
+
commit their own work first.
|
|
23
|
+
2. Read `thesis.config.yml` and the project docs in `margi/docs/`. These documents define the
|
|
24
|
+
goals that all feedback is measured against.
|
|
25
|
+
3. Do the command (below).
|
|
26
|
+
4. Run `margi finalize`. This validates your draft, injects provenance and commits `margi/`.
|
|
27
|
+
If you know your model id, pass it with `--model <id>`. If finalize reports a schema
|
|
28
|
+
error, fix the draft and run it again.
|
|
29
|
+
5. Report the result briefly to the user.
|
|
30
|
+
|
|
31
|
+
## Commands
|
|
32
|
+
|
|
33
|
+
An invocation ending in `--headless` was launched by the `margi` CLI without a human in the
|
|
34
|
+
loop. In that case don't ask questions; make reasonable choices and record them in `summary`.
|
|
35
|
+
|
|
36
|
+
| Invocation | What to do |
|
|
37
|
+
|---|---|
|
|
38
|
+
| `/margi grade <section>` | Follow `commands/grade.md` |
|
|
39
|
+
| `/margi read [pdf…]` | Follow `commands/read.md` |
|
|
40
|
+
| `/margi todos` | Follow `commands/todos.md` |
|
|
41
|
+
| `/margi onboard [--from <file>]` | Follow `../margi-onboard/SKILL.md` |
|
|
42
|
+
| `/margi challenge <aspect>` | Follow `../margi-challenge/SKILL.md` |
|
|
43
|
+
| `/margi outline` | Run `margi outline` and show the output. No draft is needed. |
|
|
44
|
+
| `/margi status` | Run `margi status` and show the output. |
|
|
45
|
+
|
|
46
|
+
## Drafts
|
|
47
|
+
|
|
48
|
+
Write exactly one JSON draft per command to `margi/.staging/<command>.json`, matching
|
|
49
|
+
`$defs/draft` in `schema/feedback.schema.json`. Fields:
|
|
50
|
+
|
|
51
|
+
- `command`, `scope`: required. `scope` is e.g. the section id `2.1`, `all`, or the aspect.
|
|
52
|
+
- `summary`: 2–5 sentences.
|
|
53
|
+
- `files_read`: every repo-relative file you read. They are hashed for the audit trail.
|
|
54
|
+
- `scores`: `{category: {score, max, rationale, comment_ids}}`.
|
|
55
|
+
- `comments`: `{id: "c1", category, severity: major|minor|note, body, anchor}`.
|
|
56
|
+
- `anchor`: `{file, line_start, line_end, quote}`.
|
|
57
|
+
- `quote` must be copied **verbatim** from that file and those lines (≤ 400 chars). Finalize
|
|
58
|
+
verifies it.
|
|
59
|
+
- `body` ≤ 1200 chars and names the problem. It never contains replacement prose.
|
|
60
|
+
- `payload`: command-specific data (see each command file).
|
|
61
|
+
- No other fields. Never include `provenance`, `run` or `schema`.
|
|
62
|
+
|
|
63
|
+
Get line numbers by reading the file with line numbers. Section ids and line ranges come from
|
|
64
|
+
`margi outline --no-save` (numbering) and the files listed in `thesis.config.yml`.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# /margi grade <section>
|
|
2
|
+
|
|
3
|
+
Grade one section against the rubric **and** against the documented project goals.
|
|
4
|
+
|
|
5
|
+
## Inputs
|
|
6
|
+
|
|
7
|
+
1. `margi/docs/*.md`: research question, dataset, method, field, structure, constraints.
|
|
8
|
+
If `margi finalize --check` warns that the docs are below the threshold:
|
|
9
|
+
- **Headless** (the invocation ends in `--headless`): the `margi` CLI already applied the
|
|
10
|
+
gate and the user chose `--force`. Grade, and say in `summary` which docs are missing.
|
|
11
|
+
- **Interactive**: tell the user and recommend `/margi onboard` first. Grade only if
|
|
12
|
+
they confirm, and say in `summary` that the result is low-confidence.
|
|
13
|
+
2. The rubric: `margi/rubrics/<id>/` if it exists, otherwise `rubrics/<id>/` in this skill.
|
|
14
|
+
`<id>` is `rubric` in `thesis.config.yml`. Read `rubric.yml` and every category file.
|
|
15
|
+
3. The section text. Run `margi outline --no-save` to see section ids, then read the
|
|
16
|
+
section's file(s) **with line numbers**. A section spans from its heading to the next
|
|
17
|
+
heading of the same or higher level, possibly across `#include`d files.
|
|
18
|
+
4. Recent records for this section in `margi/feedback/*_grade_<section>*.json`, if any.
|
|
19
|
+
Note what improved since then.
|
|
20
|
+
|
|
21
|
+
## Procedure
|
|
22
|
+
|
|
23
|
+
1. For each rubric category, decide a score on the rubric's scale using its descriptors.
|
|
24
|
+
Always judge against what the docs say this thesis is trying to do (its research question,
|
|
25
|
+
method and audience), not against a generic ideal.
|
|
26
|
+
2. Write 1–3 sentences of rationale per category, referencing comment ids.
|
|
27
|
+
3. Write anchored comments: 3–12 in total. Prioritise `major` problems such as the argument,
|
|
28
|
+
evidence, alignment with the research question, or method transparency over `minor` ones
|
|
29
|
+
(clarity, terminology, citation form). Use `note` for strengths worth keeping.
|
|
30
|
+
4. Every comment must point to a concrete passage (anchor with a verbatim quote) unless it is
|
|
31
|
+
about something missing. Missing things go without an anchor and say where the gap is.
|
|
32
|
+
5. **Never propose wording.** Say "this claim needs a source" or "the transition hides a
|
|
33
|
+
jump from X to Y". Do not say "replace with: …".
|
|
34
|
+
|
|
35
|
+
## Draft
|
|
36
|
+
|
|
37
|
+
`margi/.staging/grade.json`:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"command": "grade",
|
|
42
|
+
"scope": "2.1",
|
|
43
|
+
"summary": "...",
|
|
44
|
+
"files_read": ["chapters/02-prior-work.typ", "margi/docs/research-question.md", "..."],
|
|
45
|
+
"scores": {
|
|
46
|
+
"argument": {"score": 3, "max": 5, "rationale": "...", "comment_ids": ["c1", "c4"]}
|
|
47
|
+
},
|
|
48
|
+
"comments": [
|
|
49
|
+
{"id": "c1", "category": "argument", "severity": "major",
|
|
50
|
+
"body": "...", "anchor": {"file": "chapters/02-prior-work.typ", "line_start": 41,
|
|
51
|
+
"line_end": 43, "quote": "verbatim text from those lines"}}
|
|
52
|
+
],
|
|
53
|
+
"payload": {"section_title": "Prior Work", "previous_record": "<file name or null>"}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Then run `margi finalize` and show the user a compact table of the scores plus the major
|
|
58
|
+
comments with their line numbers.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# /margi read [pdf…]
|
|
2
|
+
|
|
3
|
+
Rate literature PDFs for their relevance to **this** thesis.
|
|
4
|
+
|
|
5
|
+
## Inputs
|
|
6
|
+
|
|
7
|
+
1. `margi/docs/*.md`, especially `research-question.md`, `field.md`, `method.md` and `structure.md`.
|
|
8
|
+
Below the docs threshold, apply the same rule as in `grade.md`.
|
|
9
|
+
2. Extracted text: run `margi extract-pdfs [pdf…]`. It prints `pdf<TAB>text-file`. Read the
|
|
10
|
+
text files, which contain `--- page N ---` markers. With no arguments, all PDFs in the
|
|
11
|
+
configured literature directory are processed.
|
|
12
|
+
3. The bibliography (`literature.bib` in the config), if any, to match PDFs to cite keys.
|
|
13
|
+
4. Previous `margi/feedback/*_read_*.json` records. Don't re-rate unchanged PDFs unless asked.
|
|
14
|
+
|
|
15
|
+
## Per PDF
|
|
16
|
+
|
|
17
|
+
- `relevance`: 0–5. 5 = central to the research question or method, 0 = unrelated.
|
|
18
|
+
- `why`: 1–3 sentences tied to a specific part of the docs.
|
|
19
|
+
- `sections`: the outline section(s) where it matters (ids or titles from `structure.md`).
|
|
20
|
+
- `role`: one of `theory | method | data | related-work | counterposition | background`.
|
|
21
|
+
- `key_passages`: up to 5 entries of `{page, quote (verbatim, ≤ 300 chars), why}`.
|
|
22
|
+
- `cite_key`: the bib key if one matches, else null.
|
|
23
|
+
- `cited_in_thesis`: true or false (grep the thesis sources for the cite key).
|
|
24
|
+
- `caveats`: limits, date, or a disputed status.
|
|
25
|
+
|
|
26
|
+
High-relevance PDFs that are not yet cited should appear first in `summary`.
|
|
27
|
+
|
|
28
|
+
## Draft
|
|
29
|
+
|
|
30
|
+
`margi/.staging/read.json`:
|
|
31
|
+
- `command`: `read`
|
|
32
|
+
- `scope`: `all` or a short list of file names
|
|
33
|
+
- `files_read`: the PDFs, the text cache files and the docs you used
|
|
34
|
+
- `payload`: `{"ratings": [{"pdf": "lit/foo.pdf", ...fields above}]}`
|
|
35
|
+
- `comments`: optional. Use them only to point at places in the thesis where a rated source
|
|
36
|
+
should be engaged with, anchored as usual.
|
|
37
|
+
|
|
38
|
+
Then run `margi finalize`.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# /margi todos
|
|
2
|
+
|
|
3
|
+
Curate a todo list **with** the human. Nothing goes to GitHub without explicit acceptance.
|
|
4
|
+
|
|
5
|
+
## 1. Gather
|
|
6
|
+
|
|
7
|
+
- The latest records in `margi/feedback/` for grade, read, outline and challenge, and their open `major` comments.
|
|
8
|
+
- `margi/docs/open-questions.md` and `structure.md` (planned vs. written, via the latest outline record).
|
|
9
|
+
- Existing proposals in `margi/todos/proposed/` and synced todos in `margi/todos/synced/`.
|
|
10
|
+
- Open GitHub issues: `gh issue list --label margi --state open --json number,title,body`.
|
|
11
|
+
If `gh` is unavailable, skip the GitHub parts and say so.
|
|
12
|
+
|
|
13
|
+
## 2. Propose todos
|
|
14
|
+
|
|
15
|
+
Write **one file per todo** to `margi/todos/proposed/<id>-<slug>.md`, where `<id>` is `t` plus
|
|
16
|
+
the date plus a counter, e.g. `t20261007-01`. Do not duplicate open issues or existing
|
|
17
|
+
proposals.
|
|
18
|
+
|
|
19
|
+
```markdown
|
|
20
|
+
---
|
|
21
|
+
id: t20261007-01
|
|
22
|
+
title: Engage with Moretti's critics in 2.1
|
|
23
|
+
status: proposed
|
|
24
|
+
section: "2.1"
|
|
25
|
+
labels: [margi, literature]
|
|
26
|
+
source: [<record file name>:<comment id>, ...]
|
|
27
|
+
---
|
|
28
|
+
What needs to happen and why, in task form (2–6 sentences). Name the evidence.
|
|
29
|
+
Never draft thesis text.
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Keep todos actionable, specific and few: 3–8 per run, prioritised.
|
|
33
|
+
|
|
34
|
+
## 3. Check completion of open issues
|
|
35
|
+
|
|
36
|
+
For each open `margi`-labelled issue, look for evidence that it is done. Evidence can be the
|
|
37
|
+
current thesis text (quote file and lines), newer grade records without the problem, updated
|
|
38
|
+
docs, or outline changes. If you find evidence, write `margi/todos/close/<issue-number>.md`:
|
|
39
|
+
|
|
40
|
+
```markdown
|
|
41
|
+
---
|
|
42
|
+
issue: 12
|
|
43
|
+
title: <issue title>
|
|
44
|
+
status: proposed
|
|
45
|
+
---
|
|
46
|
+
Evidence: ... (file:lines, record names)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## 4. Review with the human
|
|
50
|
+
|
|
51
|
+
Show both lists compactly: new todos, then proposed closures. Ask the human for each item
|
|
52
|
+
(they may answer in bulk):
|
|
53
|
+
|
|
54
|
+
- **accept** → set `status: accepted` in the file
|
|
55
|
+
- **reject** → delete the file
|
|
56
|
+
- **change** → revise the file as instructed, then show it again
|
|
57
|
+
|
|
58
|
+
Repeat until every item is accepted or rejected. Never mark anything accepted on your own.
|
|
59
|
+
|
|
60
|
+
## 5. Sync and record
|
|
61
|
+
|
|
62
|
+
1. If anything is accepted, run `margi todos --sync-accepted`. It creates issues and closes
|
|
63
|
+
issues through `gh`, then moves the files to `margi/todos/synced/`.
|
|
64
|
+
2. Write `margi/.staging/todos.json` with `command: todos`, `scope: review`, a `summary`, and
|
|
65
|
+
`payload: {"accepted": [...ids], "rejected": [...ids], "closed": [...issue numbers]}`.
|
|
66
|
+
3. Run `margi finalize`.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Alignment with research question
|
|
2
|
+
|
|
3
|
+
Does this section serve the research question and contribution documented in
|
|
4
|
+
`margi/docs/research-question.md`?
|
|
5
|
+
|
|
6
|
+
- **5**: Every part visibly advances the RQ, and the section's role in the thesis is explicit.
|
|
7
|
+
- **3**: Mostly relevant. Some passages drift, or their link to the RQ is left implicit.
|
|
8
|
+
- **1**: Unclear or no connection to the RQ, or it pursues a different question.
|
|
9
|
+
|
|
10
|
+
Look for: scope drift, passages that would fit a different thesis, sub-questions promised but
|
|
11
|
+
not addressed, terms used differently than in the docs.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Argument and reasoning
|
|
2
|
+
|
|
3
|
+
Are claims stated clearly, ordered logically and justified?
|
|
4
|
+
|
|
5
|
+
- **5**: Clear claims, explicit reasoning steps, counterarguments addressed, conclusions follow.
|
|
6
|
+
- **3**: The main line is traceable, but there are leaps, unstated premises or unaddressed objections.
|
|
7
|
+
- **1**: Assertions without reasoning, contradictions, or conclusions that do not follow.
|
|
8
|
+
|
|
9
|
+
Look for: hidden assumptions, overgeneralisation from few examples, correlation read as
|
|
10
|
+
causation (especially in computational results), circular definitions.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Evidence and sources
|
|
2
|
+
|
|
3
|
+
Are claims backed by appropriate evidence: primary sources, data, results or citations?
|
|
4
|
+
|
|
5
|
+
- **5**: Claims are consistently supported. Evidence is apt, correctly cited and interpreted with care.
|
|
6
|
+
- **3**: Mostly supported. Some claims lack sources, or evidence is over-read.
|
|
7
|
+
- **1**: Key claims are unsupported, or the evidence is misrepresented.
|
|
8
|
+
|
|
9
|
+
Look for: uncited factual claims, quotations without page numbers, results reported without
|
|
10
|
+
the data or parameters needed to interpret them, examples cherry-picked from a corpus.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Methodological transparency
|
|
2
|
+
|
|
3
|
+
Could a peer understand, assess and, where applicable, reproduce what was done? Judge this
|
|
4
|
+
against `margi/docs/method.md` and `dataset.md`.
|
|
5
|
+
|
|
6
|
+
- **5**: Method, data, parameters, tools and limitations are explicit and justified against alternatives.
|
|
7
|
+
- **3**: Method is described, but choices are not justified, or the description lacks details needed to assess it.
|
|
8
|
+
- **1**: Method unclear, or mismatched with what the docs say is planned.
|
|
9
|
+
|
|
10
|
+
Look for: undocumented preprocessing, unexplained parameter choices, missing validation or
|
|
11
|
+
evaluation, no reflection on corpus bias or the limits of operationalisation.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
id: default
|
|
2
|
+
version: "1.0"
|
|
3
|
+
title: Default rubric for humanities / digital humanities theses
|
|
4
|
+
scale:
|
|
5
|
+
min: 1
|
|
6
|
+
max: 5
|
|
7
|
+
anchors:
|
|
8
|
+
1: fails — the category's basic expectation is not met
|
|
9
|
+
2: weak — present, but with substantial problems
|
|
10
|
+
3: adequate — meets expectations with clear room to improve
|
|
11
|
+
4: good — solid, only minor issues
|
|
12
|
+
5: excellent — exemplary for an MSc thesis
|
|
13
|
+
categories:
|
|
14
|
+
- id: alignment
|
|
15
|
+
file: alignment.md
|
|
16
|
+
title: Alignment with research question
|
|
17
|
+
- id: argument
|
|
18
|
+
file: argument.md
|
|
19
|
+
title: Argument and reasoning
|
|
20
|
+
- id: evidence
|
|
21
|
+
file: evidence.md
|
|
22
|
+
title: Evidence and sources
|
|
23
|
+
- id: scholarship
|
|
24
|
+
file: scholarship.md
|
|
25
|
+
title: Engagement with scholarship
|
|
26
|
+
- id: method
|
|
27
|
+
file: method.md
|
|
28
|
+
title: Methodological transparency
|
|
29
|
+
- id: structure
|
|
30
|
+
file: structure.md
|
|
31
|
+
title: Structure and coherence
|
|
32
|
+
- id: style
|
|
33
|
+
file: style.md
|
|
34
|
+
title: Academic style and precision
|
|
35
|
+
notes: >
|
|
36
|
+
Not every category applies equally to every section (e.g. `method` for an introduction).
|
|
37
|
+
If a category does not apply, score it anyway only if meaningful; otherwise omit it and
|
|
38
|
+
explain the omission in the summary.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Engagement with scholarship
|
|
2
|
+
|
|
3
|
+
Does the section position itself within the field described in `margi/docs/field.md`?
|
|
4
|
+
|
|
5
|
+
- **5**: Engages critically with the relevant debates, including counterpositions, and makes its own position clear.
|
|
6
|
+
- **3**: Cites relevant work, but mostly summarises it, or misses an obvious camp or debate.
|
|
7
|
+
- **1**: Little or no engagement, outdated or tangential sources only.
|
|
8
|
+
|
|
9
|
+
Look for: listing instead of synthesis ("X says…, Y says…"), missing canonical works or
|
|
10
|
+
critics named in `field.md`, no statement of how this thesis differs.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Structure and coherence
|
|
2
|
+
|
|
3
|
+
Is the section organised so that a reader can follow it?
|
|
4
|
+
|
|
5
|
+
- **5**: Clear internal structure, signposting, smooth transitions, appropriate length (see `structure.md` targets).
|
|
6
|
+
- **3**: Followable, but some paragraphs are misplaced, repetitive or lack transitions.
|
|
7
|
+
- **1**: Disorganised. The reader cannot reconstruct the line of thought.
|
|
8
|
+
|
|
9
|
+
Look for: paragraphs with several topics, repeated content, sections much longer or shorter
|
|
10
|
+
than planned, conclusions that introduce new material.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Academic style and precision
|
|
2
|
+
|
|
3
|
+
Is the language precise, consistent and appropriate to the discipline? Judge this against
|
|
4
|
+
the style guide in `margi/docs/constraints.md` if one is given.
|
|
5
|
+
|
|
6
|
+
- **5**: Precise terms used consistently, appropriate register, correct citation form.
|
|
7
|
+
- **3**: Generally appropriate, with vague phrases, inconsistent terms or citation errors.
|
|
8
|
+
- **1**: Imprecise or colloquial throughout, which hinders understanding.
|
|
9
|
+
|
|
10
|
+
Point to problems; **never** supply rewritten sentences.
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/nicobenz/margi/schema/feedback.schema.json",
|
|
4
|
+
"title": "margi feedback",
|
|
5
|
+
"description": "Draft = what the agent writes to margi/.staging/. Record = draft + run + provenance, written only by `margi finalize`.",
|
|
6
|
+
"$defs": {
|
|
7
|
+
"command": {
|
|
8
|
+
"enum": ["onboard", "challenge", "grade", "outline", "read", "todos"]
|
|
9
|
+
},
|
|
10
|
+
"anchor": {
|
|
11
|
+
"type": "object",
|
|
12
|
+
"additionalProperties": false,
|
|
13
|
+
"required": ["file", "line_start", "line_end", "quote"],
|
|
14
|
+
"properties": {
|
|
15
|
+
"file": { "type": "string", "minLength": 1 },
|
|
16
|
+
"line_start": { "type": "integer", "minimum": 1 },
|
|
17
|
+
"line_end": { "type": "integer", "minimum": 1 },
|
|
18
|
+
"quote": { "type": "string", "minLength": 1, "maxLength": 400 },
|
|
19
|
+
"anchor_status": {
|
|
20
|
+
"description": "Set by finalize only.",
|
|
21
|
+
"enum": ["ok", "relocated", "unresolved"]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"comment": {
|
|
26
|
+
"type": "object",
|
|
27
|
+
"additionalProperties": false,
|
|
28
|
+
"required": ["id", "category", "severity", "body"],
|
|
29
|
+
"properties": {
|
|
30
|
+
"id": { "type": "string", "pattern": "^[A-Za-z0-9_.:-]+$" },
|
|
31
|
+
"anchor": { "$ref": "#/$defs/anchor" },
|
|
32
|
+
"category": { "type": "string", "minLength": 1 },
|
|
33
|
+
"severity": { "enum": ["major", "minor", "note"] },
|
|
34
|
+
"body": {
|
|
35
|
+
"description": "Names the problem. Never contains replacement prose for the thesis.",
|
|
36
|
+
"type": "string",
|
|
37
|
+
"minLength": 1,
|
|
38
|
+
"maxLength": 1200
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"score": {
|
|
43
|
+
"type": "object",
|
|
44
|
+
"additionalProperties": false,
|
|
45
|
+
"required": ["score", "max", "rationale"],
|
|
46
|
+
"properties": {
|
|
47
|
+
"score": { "type": "number", "minimum": 0 },
|
|
48
|
+
"max": { "type": "number", "exclusiveMinimum": 0 },
|
|
49
|
+
"rationale": { "type": "string", "minLength": 1, "maxLength": 1500 },
|
|
50
|
+
"comment_ids": { "type": "array", "items": { "type": "string" } }
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"draft_properties": {
|
|
54
|
+
"command": { "$ref": "#/$defs/command" },
|
|
55
|
+
"scope": { "type": "string", "minLength": 1, "maxLength": 120 },
|
|
56
|
+
"summary": { "type": "string", "maxLength": 3000 },
|
|
57
|
+
"files_read": {
|
|
58
|
+
"description": "Repo-relative paths the agent read. Finalize hashes them.",
|
|
59
|
+
"type": "array",
|
|
60
|
+
"items": { "type": "string" }
|
|
61
|
+
},
|
|
62
|
+
"scores": {
|
|
63
|
+
"type": "object",
|
|
64
|
+
"additionalProperties": { "$ref": "#/$defs/score" }
|
|
65
|
+
},
|
|
66
|
+
"comments": {
|
|
67
|
+
"type": "array",
|
|
68
|
+
"items": { "$ref": "#/$defs/comment" }
|
|
69
|
+
},
|
|
70
|
+
"payload": {
|
|
71
|
+
"description": "Command-specific data (outline counts, read ratings, onboard sources, challenge log, todo ids).",
|
|
72
|
+
"type": "object"
|
|
73
|
+
},
|
|
74
|
+
"agent": {
|
|
75
|
+
"description": "Self-reported by the agent; finalize records it with model_source=self-reported.",
|
|
76
|
+
"type": "object",
|
|
77
|
+
"additionalProperties": false,
|
|
78
|
+
"properties": {
|
|
79
|
+
"model": { "type": "string" },
|
|
80
|
+
"harness": { "type": "string" }
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
"draft": {
|
|
85
|
+
"type": "object",
|
|
86
|
+
"additionalProperties": false,
|
|
87
|
+
"required": ["command", "scope"],
|
|
88
|
+
"properties": {
|
|
89
|
+
"command": { "$ref": "#/$defs/draft_properties/command" },
|
|
90
|
+
"scope": { "$ref": "#/$defs/draft_properties/scope" },
|
|
91
|
+
"summary": { "$ref": "#/$defs/draft_properties/summary" },
|
|
92
|
+
"files_read": { "$ref": "#/$defs/draft_properties/files_read" },
|
|
93
|
+
"scores": { "$ref": "#/$defs/draft_properties/scores" },
|
|
94
|
+
"comments": { "$ref": "#/$defs/draft_properties/comments" },
|
|
95
|
+
"payload": { "$ref": "#/$defs/draft_properties/payload" },
|
|
96
|
+
"agent": { "$ref": "#/$defs/draft_properties/agent" }
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"provenance": {
|
|
100
|
+
"type": "object",
|
|
101
|
+
"additionalProperties": false,
|
|
102
|
+
"required": ["head_sha", "files", "model", "model_source", "margi_version", "timestamp", "docs"],
|
|
103
|
+
"properties": {
|
|
104
|
+
"head_sha": { "type": ["string", "null"] },
|
|
105
|
+
"files": {
|
|
106
|
+
"type": "array",
|
|
107
|
+
"items": {
|
|
108
|
+
"type": "object",
|
|
109
|
+
"additionalProperties": false,
|
|
110
|
+
"required": ["path", "sha256"],
|
|
111
|
+
"properties": {
|
|
112
|
+
"path": { "type": "string" },
|
|
113
|
+
"sha256": { "type": ["string", "null"] },
|
|
114
|
+
"source": { "enum": ["HEAD", "worktree", "missing"] }
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
"rubric": {
|
|
119
|
+
"type": ["object", "null"],
|
|
120
|
+
"additionalProperties": false,
|
|
121
|
+
"properties": {
|
|
122
|
+
"id": { "type": "string" },
|
|
123
|
+
"version": { "type": "string" },
|
|
124
|
+
"sha256": { "type": "string" },
|
|
125
|
+
"path": { "type": "string" }
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
"docs": {
|
|
129
|
+
"type": "object",
|
|
130
|
+
"additionalProperties": false,
|
|
131
|
+
"required": ["sha256", "completeness"],
|
|
132
|
+
"properties": {
|
|
133
|
+
"sha256": { "type": ["string", "null"] },
|
|
134
|
+
"completeness": { "type": "number", "minimum": 0, "maximum": 1 },
|
|
135
|
+
"low_confidence": { "type": "boolean" }
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
"model": { "type": ["string", "null"] },
|
|
139
|
+
"model_source": { "enum": ["wrapper", "self-reported", "none"] },
|
|
140
|
+
"harness": { "type": ["string", "null"] },
|
|
141
|
+
"margi_version": { "type": "string" },
|
|
142
|
+
"timestamp": { "type": "string" }
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
"record": {
|
|
146
|
+
"type": "object",
|
|
147
|
+
"additionalProperties": false,
|
|
148
|
+
"required": ["schema", "run", "provenance", "command", "scope"],
|
|
149
|
+
"properties": {
|
|
150
|
+
"schema": { "const": "margi/record@1" },
|
|
151
|
+
"run": {
|
|
152
|
+
"type": "object",
|
|
153
|
+
"additionalProperties": false,
|
|
154
|
+
"required": ["id"],
|
|
155
|
+
"properties": { "id": { "type": "string" } }
|
|
156
|
+
},
|
|
157
|
+
"provenance": { "$ref": "#/$defs/provenance" },
|
|
158
|
+
"command": { "$ref": "#/$defs/draft_properties/command" },
|
|
159
|
+
"scope": { "$ref": "#/$defs/draft_properties/scope" },
|
|
160
|
+
"summary": { "$ref": "#/$defs/draft_properties/summary" },
|
|
161
|
+
"files_read": { "$ref": "#/$defs/draft_properties/files_read" },
|
|
162
|
+
"scores": { "$ref": "#/$defs/draft_properties/scores" },
|
|
163
|
+
"comments": { "$ref": "#/$defs/draft_properties/comments" },
|
|
164
|
+
"payload": { "$ref": "#/$defs/draft_properties/payload" },
|
|
165
|
+
"agent": { "$ref": "#/$defs/draft_properties/agent" }
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: margi-challenge
|
|
3
|
+
description: Critically challenge the assumptions behind one aspect of the thesis project (research question, dataset, method, positioning, ...) in a dialogue, and write agreed refinements back into margi/docs/. Use for /margi challenge <aspect> or /margi-challenge.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# margi challenge <aspect>
|
|
7
|
+
|
|
8
|
+
You are a demanding but fair advisor. Your job is to **sharpen** the user's own thinking
|
|
9
|
+
about `<aspect>` by finding weak points. You do not take over the project. The user decides;
|
|
10
|
+
you probe, record and refine the documentation.
|
|
11
|
+
|
|
12
|
+
Write only to `margi/docs/` and `margi/.staging/`. Never touch thesis text.
|
|
13
|
+
|
|
14
|
+
## 0. Preflight
|
|
15
|
+
|
|
16
|
+
Run `margi finalize --check`. Stop if it fails.
|
|
17
|
+
|
|
18
|
+
## 1. Load context
|
|
19
|
+
|
|
20
|
+
- `margi/docs/*.md`, all of them. The aspect usually maps to one main doc (e.g. "dataset"
|
|
21
|
+
maps to `dataset.md`), but contradictions often hide across docs.
|
|
22
|
+
- Earlier challenge records (`margi/feedback/*_challenge_*.json`), so you don't repeat
|
|
23
|
+
settled points.
|
|
24
|
+
- The thesis text only where it shows how the aspect is actually handled.
|
|
25
|
+
- `lenses.md` in this skill: pick the 2–4 lenses that fit the aspect.
|
|
26
|
+
|
|
27
|
+
If the docs say nothing about the aspect, say so and suggest `margi onboard` first, or
|
|
28
|
+
gather the basics in this session.
|
|
29
|
+
|
|
30
|
+
## 2. Dialogue
|
|
31
|
+
|
|
32
|
+
- Start with a 2–3 sentence restatement of the user's current position on the aspect, with
|
|
33
|
+
citations to the docs, and ask whether it is accurate.
|
|
34
|
+
- Then pose **numbered challenges**, 1–3 at a time. Each one is a concrete question that
|
|
35
|
+
names the assumption being tested and why it matters for the thesis. Examples: "C3: your
|
|
36
|
+
RQ asks *why* X changed, but the method only measures *that* it changed. What licenses the
|
|
37
|
+
causal reading?"
|
|
38
|
+
- The user answers, concedes or defends. Follow up on weak answers once, then move on.
|
|
39
|
+
A defended position is a valid outcome.
|
|
40
|
+
- When a challenge leads to a refinement, restate it precisely and **ask for confirmation**
|
|
41
|
+
before writing it down.
|
|
42
|
+
- Stop after about 5–10 challenges, or when the user wants to stop.
|
|
43
|
+
|
|
44
|
+
## 3. Write back
|
|
45
|
+
|
|
46
|
+
1. Apply **only confirmed** refinements to the matching `margi/docs/*.md` sections, tagged
|
|
47
|
+
`(user, <date>, challenge)`. Keep superseded statements only if the user wants the history
|
|
48
|
+
visible; the changelog records the change either way.
|
|
49
|
+
2. Add unresolved challenges to `open-questions.md` with the date.
|
|
50
|
+
3. Append a `CHANGELOG.md` entry: date, `challenge: <aspect>`, files changed, and one line
|
|
51
|
+
per refinement.
|
|
52
|
+
4. Write `margi/.staging/challenge.json`:
|
|
53
|
+
- `command`: `challenge`
|
|
54
|
+
- `scope`: the aspect (short)
|
|
55
|
+
- `summary`: 3–6 sentences on what was tested and what changed
|
|
56
|
+
- `files_read`: the docs and thesis files you used
|
|
57
|
+
- `payload`: `{"challenges": [{"id": "C1", "lens": "...", "question": "...", "outcome": "refined|defended|open|conceded", "note": "..."}], "docs_changed": [...]}`
|
|
58
|
+
5. Run `margi finalize`.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Challenge lenses
|
|
2
|
+
|
|
3
|
+
Use the lenses that fit the aspect, and phrase every challenge concretely for this thesis.
|
|
4
|
+
|
|
5
|
+
## Assumptions
|
|
6
|
+
What has to be true for the plan to work? Which of those is unexamined? What happens if it is false?
|
|
7
|
+
|
|
8
|
+
## Scope
|
|
9
|
+
Is the question answerable within the deadline, length and corpus documented in
|
|
10
|
+
`constraints.md` and `dataset.md`? Is it too broad ("literature in the 19th century") or too
|
|
11
|
+
narrow to matter?
|
|
12
|
+
|
|
13
|
+
## Operationalisation
|
|
14
|
+
How do abstract concepts (e.g. "canon", "style", "influence") become something measurable or
|
|
15
|
+
observable? Is the operationalisation defensible in the discipline? What does it miss?
|
|
16
|
+
|
|
17
|
+
## Validity
|
|
18
|
+
- Do the methods actually answer the question (construct validity)?
|
|
19
|
+
- Could results come from corpus artefacts, OCR noise, selection or parameter choices?
|
|
20
|
+
- How far can conclusions generalise beyond the corpus?
|
|
21
|
+
|
|
22
|
+
## Alternatives
|
|
23
|
+
What is the obvious alternative method, corpus or framing, and why is it not used? Would a
|
|
24
|
+
reviewer from the neighbouring camp (e.g. close reading vs. distant reading) accept the choice?
|
|
25
|
+
|
|
26
|
+
## Positioning and contribution
|
|
27
|
+
So what? What will the field know afterwards that it did not know before? Who has done
|
|
28
|
+
something close, and what exactly is different?
|
|
29
|
+
|
|
30
|
+
## Consistency
|
|
31
|
+
Do the research question, method, dataset and planned structure fit together? Does the
|
|
32
|
+
structure give the most space to what the RQ makes central?
|
|
33
|
+
|
|
34
|
+
## Ethics and data
|
|
35
|
+
Copyright, licensing, personal data, representation of marginalised voices in the corpus.
|