Read what was said in the channels this desk is allowed to read, work out where each milestone actually is, and write three files: the one that leaves the building, the one that goes to whoever edits the tracker, and the one that goes to the project manager alone.
Two sentences decide everything here.
Slippage is a property of a sequence of dates, not of a date. A milestone that moved once by seven weeks and one that moved three times in a fortnight can show the same number of days, and they are completely different projects. So the baseline is never edited, every movement is an append, and the sequence is what gets reported. The other half of the same sentence: a date that moved on a recorded decision is not slippage. A movement carries a decision reference or it does not, and one with nothing behind it is reported as a slip — the honest default, and the thing that makes people record decisions.
A status this tool proposed is not evidence, and the next run must
not be able to read it back as any. This package writes proposals a
person applies; it never writes the tracker. Every run re-derives the
whole picture from the messages alone, and the register it writes is
an output that nothing ever reads. The other half: never paraphrase
a status into something stronger. words and read_as are two
columns, and a reading stronger than its words produces no proposal at
all — and is never softened either, because reading it down is the
same mistake in the other direction with just as little behind it.
plugins/gp-12-project-status-update-manager/ |
the skill: seven scripts, three empty templates, one reference note |
Sample Input/ |
13 files, 10,364 bytes — an invented desk with three projects |
Sample Output/ |
160 files, 127,680 bytes — every report, every written file, and 145 refusals |
Build Tools/fixture/verify.py |
3,301 lines, 700 checks, no failures |
Caldevaz is invented, and so is every person, project, channel,
message, milestone, decision, blocker and risk in it. Three projects:
Harbour Gate, whose report leaves the building; Ledger
Migration, whose report was decided not to; and Kiln
Replacement, where nobody has decided either way — which is a third
state and not a no.
The centrepieces are all in the sample, and the harness reads each one off the written files:
- M-01 has drifted 49 days: 28 nobody decided for, and 21 a recorded decision paid for. Two slips, 45 days apart, and not a pattern.
- M-02 has drifted 28 days across three slips inside 16 days, and is a pattern. Same threshold, different answer, because the window is what decides.
- RD-05 reads
nearly doneasdeliveredand produces no proposal; RD-12 readsis done - we ran it end to endasdeliveredand produces one. Same reader, same word, opposite outcome. - RD-13 reads
is at risk, which is not one of the four states a milestone can be in — so it goes to the manager to look at rather than being rounded toblockedso that something could be applied. - M-03 is blocked 12 days and silent 12 days: at risk on two counts while its date has never moved.
- M-06 has been silent 24 days; M-07 and M-08 have never been mentioned at all, which is a different state and a worse one.
- X-03 (capacity) and X-05 (conflict) go to the manager and nowhere else, and X-05 names the client's own representative.
| file | reader | carries | must never carry |
|---|---|---|---|
reports/<project>.docx |
the client | milestone states, dates with the decisions behind them, standing blockers, non-people-sensitive risks | any capacity, performance or conflict risk; any unapproved change |
proposals/<project>.txt |
whoever edits the tracker | every change, each with the message, the speaker, the channel, the moment and the words | any people-sensitive risk; the report's byline |
digests/<project>.txt |
the project manager alone | people-sensitive risks in full, and everything still waiting on them | the report's byline; any claim that something was done |
register.txt |
nobody | what this run produced | anything a later run reads |
Every check runs over the files as written, not over the values
that produced them. The Word document is opened again with a Word
library and read back paragraph by paragraph — tables, headers and
footers included — because a .docx is a zip full of XML and a
template can put a line in front of a reader without any variable in
the program ever holding it.
And the check runs in both directions. The report is checked for the absence of every people-sensitive risk, and the digest is checked for the presence of every one of them, because a check that only looked for absence would pass on a run that dropped the risk altogether — and a dropped risk is worse than a misfiled one, since nobody is looking for it.
scripts/mandate_report.py can this desk be reported on at all
scripts/channel_report.py what each project's status rests on
scripts/capture_report.py what was said, and what it was read as
scripts/movement_report.py the dates, and what moved them
scripts/risk_report.py what is at risk, and who is told
scripts/handoff_report.py what a person still has to do
scripts/build_updates.py the three files, and the checks on them
python3 scripts/mandate_report.py \
--mandate "Sample Input/desk-mandate.yaml" \
--team "Sample Input/desk-team.yaml" \
--policy "Sample Input/status-policy.yaml"
python3 scripts/build_updates.py \
--mandate "Sample Input/desk-mandate.yaml" \
--team "Sample Input/desk-team.yaml" \
--policy "Sample Input/status-policy.yaml" \
--out updates/
Exit 0 clean, 1 findings, 3 refused. The three governing files
ship empty; the first run refuses once and lists every gap in all
three together.
The Word document needs python-docx. Without it the run refuses and
says so rather than writing a text file instead — a text file sent to
a steering group in place of the document they expect is a different
deliverable, not a degraded one.
python3 "Build Tools/fixture/verify.py"
700 checks, no failures, in either layout — the build tree or this repository — and it says which it found. Eight passes:
| pass | what it asserts |
|---|---|
| COVERAGE | 50 codes, 36 refused switches and 132 named refusals, each reached by something here or recorded with the reason it cannot be |
| CONTACT | no address and no telephone number anywhere, with an empty exemption list asserted empty and five planted examples the probes must find |
| PUBLICATION | no real project-management, messaging, mail, calendar, document, transcription or automation product named, with 22 candidates written down as deliberately absent and 8 exempt files walked again by a narrower check |
| MANIFEST | the plugin can install: frontmatter shape, and a description inside 1024 in characters and in bytes |
| INVARIANTS | the three figures, the pattern, the hedge, the split in both directions, the register as an output only, two runs agreeing, silence measured from the day the words were said, and the window governing the messages and nothing else |
| NEGATIVE | 34 codes with a variant that silences them, 16 with a written reason they cannot have one, and one positive control |
| MUTATION | 32 mutations: 7 in the gone sense and 25 in the appears sense, each naming the refusal's own sentence |
| HYGIENE | source, printed output and written files inside 78 characters; nothing imported or defined and unused; 131 variants each proved to change what some script prints |
It applies nothing, sends nothing, closes no milestone, changes no owner, writes no date into a tracker and deletes nothing — including a reading that a later one overtook, which is named rather than dropped so the person who remembers sending it can see where it went.
It scores nothing and ranks nothing. The bottom of a ranked list is where a risk goes to be ignored with a number attached, and the number would have come from this tool rather than from anybody who knows the project. What it reports instead is three independent measurements per milestone — days slipped that no decision paid for, days a blocker has stood, and days since anybody said a word about it — and how many of the three are saying something.
There is no address and no telephone number anywhere in this package, in any table or any output, for the same reason the split between the three files exists: it writes a document that leaves the building.