Skip to content

feat: persist provided artefacts and condition facts per model - #46

Merged
Mearman merged 9 commits into
mainfrom
feat/artefact-facts
Oct 11, 2026
Merged

Mearman merged 9 commits into
mainfrom
feat/artefact-facts

Conversation

@Mearman

@Mearman Mearman commented Oct 11, 2026

Copy link
Copy Markdown
Member

Closes #35

The store now keeps a fact record per model beside the overlay: graph-domain's new FactRecord, with artefacts (artefact id to true provided or false known absent) and values (fact name to a trilean ComputedValue). Anything the record does not name is unknown, so an artefact has three states and a named fact stays indeterminate until set. factsFrom(record) in graph-domain adapts it to the Facts port, answering string keys as named facts and artefactKey(id) keys from artefacts; layeredFacts puts the stored record ahead of facts a host injects, and factNamesIn lists the names a condition reads.

The v1 store contract gains facts.read, facts.set (merge by name) and facts.clear (named entries, or { all: true }), and models.load returns facts beside overlay. A facts write takes a revision and publishes a facts change. Saving a model drops facts about artefacts it no longer declares and keeps named facts; a fact about an undeclared artefact is rejected as unknown-reference; deleting a model drops its facts. The fake and the SQLite store implement it (artefact_facts and named_facts tables, committed drizzle-kit migration), and the conformance kit covers it, including two subscribers hearing each facts write and the stored record driving deriveStatuses. The SQLite test checks facts survive reopening the file.

The CLI gains set artefact <id> <provided|absent|unknown>, set fact <name> <value> [--text] (true/false booleans, a JSON number, otherwise text; unknown clears) and facts; set <id> <state> is unchanged. ready, blocked, impact, path and why reason over the stored record ahead of the host's facts. add activity gains --consumes and --produces so an input artefact can be wired from the command line at all. show draws structure only, so facts do not change it.

The web app reasons over the stored record, and the details panel gains Provided/Absent/Unknown buttons for each artefact the selected element consumes or produces, and True/False/Unknown buttons for each named fact the conditions around it read; the view's statuses follow through the existing model subscription.

I broke each capability once (domain artefact and named lookups, the fake's merge, save narrowing and clear, the SQLite write and feed, the CLI and web reading the record) and each was caught by the new tests.

@Mearman
Mearman marked this pull request as ready for review October 11, 2026 10:12
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
🔒 Security Review ✅ Completed 2026-10-11T11:38:07.613695Z b7e1aea Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@Mearman

Mearman commented Oct 11, 2026

Copy link
Copy Markdown
Member Author

@codex security review

@Mearman
Mearman force-pushed the feat/artefact-facts branch from f88ffd4 to eb90b8e Compare October 11, 2026 10:12
@Mearman

Mearman commented Oct 11, 2026

Copy link
Copy Markdown
Member Author

@codex security review

@Mearman
Mearman force-pushed the feat/artefact-facts branch from eb90b8e to 5c89e09 Compare October 11, 2026 10:15
@Mearman

Mearman commented Oct 11, 2026

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review

Security review completed. No security issues were found in this pull request.

Reviewed commit: 5c89e09b89

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

FactRecord is the plain-data shape of what is known from outside a run:
artefacts known provided or not, and named facts with their trilean values,
each unknown when absent. factsFrom answers the Facts port from it, and
layeredFacts lets an earlier port override a later one only where it knows.
Adds facts.read, facts.set and facts.clear to the v1 router and returns
the record from models.load, so which artefacts are provided and the
values conditions read persist beside the overlay. A facts write takes a
revision and is published as a facts change. Saving a model drops facts
about artefacts it no longer declares; a fact about an undeclared artefact
is rejected as an unknown reference. The fake implements it and the
conformance kit covers it, including the reasoning over the stored record.
Adds the artefact_facts and named_facts tables with a committed
drizzle-kit migration, and implements facts.read, facts.set and
facts.clear over them. Saves, upserts and deletes keep the record
consistent in the same transaction as the model's rows, and a facts
write takes a revision and publishes a facts change. Facts survive the
database file being opened again.
factNamesIn walks a trilean condition and returns the string key of each
reference node, so a consumer can offer controls for the facts that decide
a transition.
set artefact <id> <provided|absent|unknown> and set fact <name> <value>
write the model's fact record in the store, and facts lists it. ready,
blocked, impact, path and why read the stored record ahead of the host's
facts, so a consumer of an input is ready once it is set provided and a
stored fact decides a branch. add activity gains --consumes and
--produces so artefacts can be wired from the command line.
and and or are binary in trilean; allOf and anyOf take operand lists.
The workspace reasons over the stored fact record, and the details of the
selected element gain buttons that record each artefact it consumes or
produces as provided, absent or unknown, and each named fact the
conditions around it read as true, false or unknown. The model follows
the store, so the statuses update as soon as a change commits.
@Mearman
Mearman force-pushed the feat/artefact-facts branch from 5c89e09 to b7e1aea Compare October 11, 2026 11:33
@Mearman

Mearman commented Oct 11, 2026

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review

Security review completed. No security issues were found in this pull request.

Reviewed commit: b7e1aea330

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@Mearman
Mearman merged commit 12c5397 into main Oct 11, 2026
@Mearman
Mearman deleted the feat/artefact-facts branch October 11, 2026 12:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Persist facts (provided artefacts, condition values) in the store so set can record them

1 participant